Strange output after putting a "prime" on an identifier in Racket REPL - racket

Today, I made a typing mistake in the REPL and discovered a strange behaviour. Here's a sample of the interaction:
Welcome to Racket v6.11.
> (define x 3)
> x
3
> x'
3
> x
'x
>
So the first x I typed resulted in 3, which is expected. The x' I accidentally typed resulted in 3, which is unexpected. The last x resulted in 'x (!!).
It seems like there is something I don't understand about how the REPL reads values. Could someone explain why the REPL behaves in this way?

See Racketrivia: Using ' as an "identifier suffix" on the racket mailing list. The reply by Robby Findler and the reply by Matthias Felleisen both explain this.
The first line, x, is normal.
The second line, x', is actually an "expression and-a-half." It's interpreted as an expression x followed by an unfinished expression '. The unfinished expression is allowed to be finished on the next line. Whatever you put on the next line will be put as the second half of ' next-line.
That means the third x is actually interpreted as the second half of ' x.
You can see a better example of unfinished expressions with parentheses:
> 1 (list 2 ; 1 followed by an unfinished expression
1
> 3 4) ; finishing it
'(2 3 4)
> 3 4) ; on its own without the `(list 2` before it it's an error
3
4
; readline-input:13:3: read-syntax: unexpected `)` [,bt for context]
The quote after an expression is interpreted in a similar way:
> 1 ' ; 1 followed by an unfinished expression
1
> (indefatigable inexhaustible) ; finishes previously unfinished, put after a quote
'(indefatigable inexhaustible)
> (indefatigable inexhaustible) ; on its own without the quote before it it's an error
; indefatigable: undefined;
; cannot reference an identifier before its definition
; in module: top-level
; internal name: indefatigable

Related

kdb: can the $ function take 5 arguments?

From https://code.kx.com/q/wp/parse-trees/#the-solution
I came across below function, which translates enlisted symbols or symbol lists into the string "enlist".
ereptest:{ //returns a boolean
(1=count x) and ((0=type x) and 11=type first x) or 11=type x}
ereplace:{"enlist",.Q.s1 first x}
funcEn:{$[ereptest x;ereplace x;0=type x;.z.s each x;x]} <<<<<
In last line, it seems $ is applied to 5 arguments, but this page shows $ is of rank 2 or 3. What am I missing here?
From the kx wiki
Odd number of expressions
For brevity, nested triads can be flattened.
$[q;a;r;b;c] <=> $[q;a;$[r;b;c]]
These two expressions are equivalent:
$[0;a;r;b;c]
$[r;b;c]

Currying in Typed Racket

In regular Racket, ((curry * 2) 3) works as expected, with 6 as a result.
However, in Typed Racket:
> ((curry * 2) 3)
; readline-input:3:0: Type Checker: could not apply function;
; wrong number of arguments provided
; expected: 0
; given: 1
; in: ((curry * 2) 3)
; [,bt for context]
Why?
I believe it has something to do with the fact that * can take only one argument, so when you curry it with a parameter, it is returning a procedure that takes no additional arguments. Type (curry * 2) at the command line in typed/racket and observe the result: (-> Number).
Note that there is only a return type and no parameter. I don't see a way around this in typed racket, but I hope that at least explains why it is happening. You should be safe to use currying with more complex procedures as long as they do not have an option to take only one parameter.

Quote-unquote idiom in Julia & concatenating Expr objects

I'd like to write a simple macro that shows the names & values of variables. In Common Lisp it would be
(defmacro dprint (&rest vars)
`(progn
,#(loop for v in vars
collect `(format t "~a: ~a~%" ',v ,v))))
In Julia I had two problems writing this:
How can I collect the generated Expr objects into a block? (In Lisp, this is done by splicing the list with ,# into progn.) The best I could come up with is to create an Expr(:block), and set its args to the list, but this is far from elegant.
I need to use both the name and the value of the variable. Interpolation inside strings and quoted expressions both use $, which complicates the issue, but even if I use string for concatenation, I can 't print the variable's name - at least :($v) does not do the same as ',v in CL...
My current macro looks like this:
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println(string(:($v), " = ", $v))) for v in vars]
ex
end
Looking at a macroexpansion shows the problem:
julia> macroexpand(:(#dprint x y))
quote
println(string(v," = ",x))
println(string(v," = ",y))
end
I would like to get
quote
println(string(:x," = ",x))
println(string(:y," = ",y))
end
Any hints?
EDIT: Combining the answers, the solution seems to be the following:
macro dprint(vars...)
quote
$([:(println(string($(Meta.quot(v)), " = ", $v))) for v in vars]...)
end
end
... i.e., using $(Meta.quot(v)) to the effect of ',v, and $(expr...) for ,#expr. Thank you again!
the #show macro already exists for this. It is helpful to be able to implement it yourself, so later you can do other likes like make one that will show the size of an Array..
For your particular variant:
Answer is Meta.quot,
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println($(Meta.quot(v)), " = ", $v)) for v in vars]
ex
end
See with:
julia> a=2; b=3;
julia> #dprint a
a = 2
julia> #dprint a b
a = 2
b = 3
oxinabox's answer is good, but I should mention the equivalent to ,#x is $(x...) (this is the other part of your question).
For instance, consider the macro
macro _begin(); esc(:begin); end
macro #_begin()(args...)
quote
$(args...)
end |> esc
end
and invocation
#begin x=1 y=2 x*y
which (though dubiously readable) produces the expected result 2. (The #_begin macro is not part of the example; it is required however because begin is a reserved word, so one needs a macro to access the symbol directly.)
Note
julia> macroexpand(:(#begin 1 2 3))
quote # REPL[1], line 5:
1
2
3
end
I consider this more readable, personally, than pushing to the .args array.

Explain me my LISP code

I'm new in LISP and I'm trying to understand recursion.
What I know is that recursion needs a STOP condition. In my code below, can you explain to me why (equal x 0) 1 is my STOP condition SINCE fact(- X 1) could continue indefinitely as in my second condition, I have set to t the second line of my cond which means it should continue.
BUT when I run the program, it works fine though. Below is my code (found by chance)
(defun fact(x)
(cond
((equal x 0) 1)
(t (*(fact(- x 1)) x))
)
)
cond expresssions have a number of clauses. Each clause is of the form (expr1 expr2). If the expr1 evaluates to true then expr2 is evaluated and that is the returned value of thecond`. No other clauses are evaluated.
So, once x becomes 0 the first clauses of cond evaluates to true and that call to fact returns 1.
The other clause of cond has a first expression of t which is true by definition; thus if the first clause is not used it always uses the second clause. (A cond clause with t is like an "else" in an "if" statement in other langugaes.)
This function is recursive, if you call it with an argument of 2, it checks if 2 == 0, it doesn't so then it multiplies 2 with the value returned by recursively calling itself with 1. Since 1 != 0 it will return the value of 1 multiplied by the value of recursively calling itself with 0. Since 0 does equal 0 it just returns 1, which is used one layer to return 1 which is then used at the top layer of this recursion to return 2.
Common Lisp has a function trace which will let you see when your function is called and with what arguments. Typically each recursive call will be indented so you can see something like this:
(fact 2)
(fact 1)
(fact 0)
Which can be helpful for understanding this function.
(As mentioned in a comment - this function doesn't catch the case of a negative input - but that is error handling and could be easily fixed).

Are the variables *,+, and / bound to recent input in SLIME or Clozure CL?

I was messing around in SLIME (connected a Clozure REPL) when I discovered this:
It looks like the variables +, *, and / are all bound to some variation on recent input, + is the input itself, * is the result of evaluating that input, and / is the result contained in a list.
Is this right? Who is responsible for this, SLIME or Clozure? I couldn't find anything in the SLIME manual.
Thanks!
; SLIME 2010-05-13
CL-USER> +
NIL
CL-USER> *
NIL
CL-USER> /
(NIL)
CL-USER> -
-
CL-USER> +
-
CL-USER> (list 1 2)
(1 2)
CL-USER> +
(LIST 1 2)
CL-USER> /
((LIST 1 2))
CL-USER> (+ 1 2)
3
CL-USER> /
(3)
CL-USER> *
(3)
CL-USER> (* 1 2)
2
CL-USER> *
2
CL-USER>
Those are all, and more, specified by the Common Lisp standard. Search the environment dictionary for 'Variable'.
+
++
+++
While a form is being evaluated by the top-level loop, the variable + is bound to the previous form read by the loop. The variable ++ holds the previous value of + (that is, the form evaluated two interactions ago), and +++ holds the previous value of ++.
-
While a form is being evaluated by the top-level loop, the variable - is bound to the form itself; that is, it is the value about to be given to + once this interaction is done.
*
**
***
While a form is being evaluated by the top-level loop, the variable * is bound to the result printed at the end of the last time through the loop; that is, it is the value produced by evaluating the form in +. If several values were produced, * contains the first value only; * contains nil if zero values were produced. The variable ** holds the previous value of * (that is, the result printed two interactions ago), and * holds the previous value of **.
/
//
///
While a form is being evaluated by the top-level loop, the variable / is bound to a list of the results printed at the end of the last time through the loop; that is, it is a list of all values produced by evaluating the form in +. The value of * should always be the same as the car of the value of /. The variable // holds the previous value of / (that is, the results printed two interactions ago), and /// holds the previous value of //. Therefore the value of ** should always be the same as the car of //, and similarly for * and ///.
From Common Lisp the Language, 2nd Edition 20.2