From what I can tell, Racket has no notion of a “private” module, that is, one which cannot be accessed except by certain internal modules?
No. Often you’ll see a private
subdirectory, which is merely a signal that anything in there shouldn’t be considered public interface.
Apropos private - can anyone remember the year when the ICFP contest was run by Racket people? There were a #lang
were the body of the module was encrypted. In this way it was possible send the participants a program to run, but they couldn’t tamper with the source.
That’s a clever use of #lang
.
Wait, if everything runs locally, then you can just fork the reader to make it output an actual program, which you can then tamper with, no?
Maybe. I can’t remember much about it. It was a Cops and Robbers game inspired by Chicago (I think).
I want to be able to see if an identifier is bound to a macro. Is there a reliable way to do that?
(It occurs to me that I should be using continuations both to thread state and to handle failure in a more graceful way.)
Yes - exactly like this.
Is it possible to introspect the body of a procedure in the REPL? Like in R where typing a function name returns the implementation.
Not trivially
Though to be fair, DrRacket via syntax-check can bring you to the definition of the function if it’s a define
, so it should be possible from the repl to do something similar.
This isn’t sufficient to prevent tampering, right? It’s just base 64 encoding/decoding.
More importantly you can easily copy/modify framework/private/decode
to spit out the actual module
(that is, even if it were encrypted)
True. Maybe I am misremebering. Maybe only the zo-files were distributed?
A .plt file was provided, but once it’s installed, the source should be accessible. This is just a development kit, so probably looking at the source was not helpful.
Are you trying to, for instance, provide a reference implementation for students that they can use to see its behaviour but not its code? You could compile using Chez. I have also used a submission server to provide this functionality.
You found it! The trip down memory lane was just an association due to the “private module” question.
It looks like the best I can get is to use syntax-local-value
then check for a procedure with an arity of 1.
when upgrading versions of racket, is it possible to keep all your old settings for drracket?
That should be automatic
doesn’t happen for you?
nope.
Try (find-system-path 'pref-file)
This should give you the location of the file with all your settings
./racket-7.9-x86_64-linux.sh
This program will extract and install Racket v7.9.
Note: the required diskspace for this installation is 531M.
Do you want a Unix-style distribution?
In this distribution mode files go into different directories according
to Unix conventions. A "racket-uninstall" script will be generated
to be used when you want to remove the installation. If you say 'no',
the whole Racket directory is kept in a single installation directory
(movable and erasable), possibly with external links into it -- this is
often more convenient, especially if you want to install multiple
versions or keep it in your home directory.
Enter yes/no (default: no) > no
Where do you want to install the "racket" directory tree?
1 - /usr/racket [default]
2 - /usr/local/racket
3 - ~/racket (/home/.../racket)
4 - ./racket (here)
Or enter a different "racket" directory to install in.
> ~/tools/racket
Checking the integrity of the binary archive... ok.
"/home/.../tools/racket" exists, delete? yes
Deleting old "/home/.../tools/racket"... done.
Unpacking into "/home/.../tools/racket" (Ctrl+C to abort)...
Done.
If you want to install new system links within the "bin", "man"
and "share/applications" subdirectories of a common directory prefix
(for example, "/usr/local") then enter the prefix of an existing
directory that you want to use. This might overwrite existing symlinks,
but not files.
(default: skip links) >
Installation complete.
oh! I see what happened. My color theme and file-viewer are available through plugins which needed to be reinstalled. After installing them everything went back to normal
You should just have to migrate them
either use raco pkg migrate .....
which requires to know the version of racket you just uninstalled
Or try running this script for ease of use: https://gist.github.com/Metaxal/13c4effc483c5ef9f5797ace4950f97a (and let me know whether it works)
yup that works perfectly
thank you, as always :heart:
my pleasure!
If I wanted to create a procedure that takes an arbitrary number of parameters (like +
or and
, etc.) what would the definition look like? What I’m thinking is (define (some-thing . ... xs)
(cond [(empty? xs) 'default]
[(some-test? (first xs)) (cons (some-thing-else (first xs)) (some-thing (rest xs)]
[else (some-thing (rest xs))]))
and calling it like (some-thing 'a 'b 'c 'd 'e)
or (some-thing 'c 'f)
or (apply some-thing '(a b c d e f))
as far as arguments. It seems I’m overlooking something obvious.
(define (something . xs) (displayln xs))
(something 1 2 3)
will print (1 2 3)
I’m having trouble calling that recursively. Similar to my example, I’d like to call (some-thing (rest xs))
but that seems to cause an infinite loop. Is it not possible with a single procedure, i.e. maybe I need an inner-function to call only after the parameters are formed into a list?
Use (apply something (rest xs))
.
Well when you say it like that it sounds so easy :face_palm: Thanks, extremely helpful!
It’s a pattern. If f
is a variadic functioned, then (apply f xs)
is needed to call the function f
with arguments xs
.
So (define (thing . xs)
is called a “variadic function” because of the .
? And calling it as (thing 1 2 3)
packages the 1, 2, 3 into a list but calling it as (apply thing '(1 2 3))
first unpackages it and passes each member of the list as a parameter then the . xs
packages it back up as a list?
Perfect explanation.
Thank you, thank you. That answered so many questions!
Just to check that a new list is allocated, I made a quick test: > (define xs '(1 2 3))
> (define (f . ys) (eq? ys xs))
> (apply f xs)
#f
With immutable lists I guess it would be ok for xs
and ys
to be the same list. In Scheme, where lists are mutable, the spec says, that apply
must allocate a new list (so the caller knows, the callee doesn’t mutate the list).
That’s an insightful little test. I think my initial problem was that I tried to recurse with (thing (rest xs))
which basically wrapped xs
in a list so that (empty? xs)
was always false because the list looked like '((1 2 3))
or eventually '(())
, causing an infinite loop.
Thanks for all your help. I see your name everywhere so I can only imagine how busy you are. Thanks for giving back to your community
Yep. Seeing an extra list often means that an apply
was forgotten somewhere.
@jburgess84 has joined the channel
Is it possible to implement an apply
that doesn’t allocate a new list, without going deep into Racket internals?