racket scheme redefinition of constants - function

I am currently using racket scheme with DrRacket as the editor for some exploratory programming. When I try and redefine a function I get the following message:
define-values: cannot re-define a constant: png->byte-list
Now I used to accept that this was a property of the language and was frustrated by it but kind of accepted it. Having read How can you re-define a constant identifier in DrScheme? I can see that I don't necessarily have to accept this limitation.
My questions are as follows:
Is this feature only available in the R5RS language? Is there a way to switch this feature off for an arbitrary language?
Alternatively if I switch the R5RS language will this have an impact on me using the modules I'm using at the moment: racket/gui/base and web-server/insta?

Such re-definitions are possible with #lang racket if you do them in the definitions window. The thing to keep in mind is that this is not a kind of mutation (which is common with R5RS implementations), for example, this:
#lang racket
(define orig-+ +)
(define + whatever)
will not have orig-+ bound to the real addition function. When this module is compiled, Racket knows (statically) that + is something that you define, so any references to it are references to your own definition -- so the above code will bind orig-+ to the "uninitialized" value of +. If you really want to do something like that, then you can require the original + under a different name:
#lang racket
(require (rename-in racket [+ orig-+]))
(define + whatever)
On top of that, there's inlining that happens when the module is compiled -- which is a different issue. Racket will usually want to inline references to bindings that are never mutated in the code, so if you try that last piece of code you will not be able to further redefine + on the REPL. You can deal with that in one of two ways -- the first is to mutate the binding explicitly:
#lang racket
(require (rename-in racket [+ orig-+]))
(define + #f)
(set! + whatever)
which makes the compiler avoid any inlining. Another option is that DrRacket flag, which turns on a compiler flag that avoids all inlining. Note that the speed penalty for this can be significant.

1 - I'm no pro in Scheme, but I just tried to redefine multiplication function (* ).
It doesn't work with "Disallow redefinition of initial bindings". But if unchecked - it works:
Welcome to DrRacket, version 5.0.2 [3m].
Language: R5RS [custom]; memory limit: 128 MB.
> (* 2 2)
4
> (define (* a b) a)
> (* 2 2)
2
>
However, I was not able to get your error (define-values: cannot re-define a constant:...)
If i redefine existing function i get (define-values: cannot change constant variable:...)
2 - I would think that if modules have #lang directive that specifies explicitly the language it should not be a problem (I guess).

Here is how to define multiplication
(define multiply *) ; variable named "multiply" with a value of *

Related

Clojure/Clojurescript: Argument to resolve must be a quoted symbol

I'm attempting to use a string saved in a variable to call a function like so:
(defn update-product-list [] "Test")
(defn handle-state-change [action]
((resolve (symbol action))))
(handle-state-change "update-product-list")
However, this gives me the following error: Assert failed: Argument to resolve must be a quoted symbol
I've also tried changing the above line to:
((resolve (quote (symbol action))))
But this still gives an error. I also tried changing it just to:
((resolve 'action))
But this gives a different error I don't quite understand: js/action is shadowed by a local. I don't want to override the function just call it. Not sure where I'm going wrong. I've looked at a few examples, but can't see to pin it down.
ClojureScript supports :advanced optimization, in which Google Closure Compiler will rename, inline, or eliminate (unused) functions in order to implement minification. In short, the name of the function you want to look up will, in general, simply no longer exist under :advanced.
Because of this, ClojureScript's resolve is a compile-time facility (a macro requiring a literal quoted symbol).
If you are using :simple or self-hosted ClojureScript, more options are available to you because the support needed persists into runtime. For example Planck has a planck.core/resolve that behave's like Clojure's resolve. A similar approach is possible in Lumo, and similar facilities can be fashioned if using :simple.
In general though, given :advanced, if you need to map strings to a set of functions, you need to somehow arrange to have a static mapping constructed at compile time to support this (the set of functions must be known a priori, at compile time).
If you have a namespace (the name of which is statically known at compile time) which defines functions that need to be dynamically called via strings, you could consider making use of ns-publics:
cljs.user=> (ns foo.core)
foo.core=> (defn square [x] (* x x))
#'foo.core/square
foo.core=> (in-ns 'cljs.user)
nil
cljs.user=> (when-some [fn-var ((ns-publics 'foo.core) (symbol "square"))]
(fn-var 3))
9
This will work under :advanced. The mapping constructed by ns-publics is static; built at compile-time. If you have multiple namespaces that need such treatment, you could merge several calls to ns-publics to build a larger map.
The advantage of this approach is that the code involved is pretty short and requires little maintenance. The disadvantage is that it dumps all of the public vars of the namespace (foo.core in this example) into your generated code (and the generated code for vars is somewhat verbose). Another disadvantage is that you need to statically know the namespace(s) involved at compile time.
If you need to further minimize generated code size, you could just build / maintain a simple static map from string to function value as in
(def fns {"square" foo.core/square})
and use it appropriately, keeping it up to date as your codebase evolves.
Another option would be to mark the functions that you need to access using ^:export meta, and then to call those functions using JavaScript interop. For example if you define the function this way
(defn ^:export square [x] (* x x))
then you can use strings / interop to lookup the function and call it at runtime. Here's an example:
((goog.object/getValueByKeys js/window #js ["foo" "core" "square"]) 3)
The use of ^:export and :advanced is covered here. If you know that you are using :simple or less, then you can simply use JavaScript interop to call the functions of interest, without needn't to use ^:export.
Note that there is no general solution that would let you look up a function by name at runtime under :advanced without somehow putting some aspect of that function into your code at compile time. (In fact, if a function is not referenced in a way that Google Closure Compiler can statically, see, the function implementation will be completely eliminated as dead code.) In the above, ns-publics grabs all the vars for a namespace at compile time, rolling your own lookup map sets up static code to refer to the function value, and using ^:export statically arranges to make the name of the function persist into runtime.
You need to use it like this:
((resolve 'inc) 5)) => 6
or, deconstructed a bit:
(let [the-fn (resolve 'inc)]
(the-fn 7))
=> 8
If you have the function name as a string, use the symbol function to convert from string => symbol (from clojuredocs.org):
user=> ((-> "first" symbol resolve) [1 2 3])
1
And, never forget the Clojure CheatSheet!

How to pass `and` as a function in Racket?

For the following code:
(foldl and #t '(#t #f))
Racket returns:
and: bad syntax in: and
I know and is not a function. And I can circumvent this problem using lambda:
(foldl (lambda (a b) (and a b)) #t '(#t #f))
I have 2 questions here:
and is not a function. Then what is it? Is it a macro?
My solution using lambda seems ugly. Is there a better way to solve this problem?
Thank you.
It is a conditional syntactic form, or it might be implemented as a macro that expands to some core syntax form, which is treated as a special case by the compiler/interpreter.
The list there in Racket's docs includes if as a special form but doesn't include and, so the latter most probably is implemented in terms of the former. But R5RS does list and as a syntactic keyword. So, best we can say, it's either a special syntax, or a macro.
It is easy to re-write any and form (and a b c ...) as an if form, (if a (if b (if c #t #f) #f) #f).
lambda is fine by me, but you can also use every from SRFI-1 (or Racket's andmap):
(every identity '(#t #f))
should return #f.
edit: except, as Joshua Taylor points out, calling your lambda through a function like foldl does not short-circuit. Which defeats the purpose to calling the and in the first place.
Another thing is, in Racket's foldl the last argument to lambda is the one that receives the previous result in the chain of applications; so the implementation should really be
(foldl (lambda (a b) (and b a)) #t '(#t #f))

Is the Macro argument a function?

I am trying to determine whether a given argument within a macro is a function, something like
(defmacro call-special? [a b]
(if (ifn? a)
`(~a ~b)
`(-> ~b ~a)))
So that the following two calls would both generate "Hello World"
(call-special #(println % " World") "Hello")
(call-special (println " World") "Hello")
However, I can't figure out how to convert "a" into something that ifn? can understand. Any help is appreciated.
You might want to ask yourself why you want to define call-special? in this way. It doesn't seem particularly useful and doesn't even save you any typing - do you really need a macro to do this?
Having said that, if you are determined to make it work then one option would be to look inside a and see if it is a function definition:
(defmacro call-special? [a b]
(if (#{'fn 'fn*} (first a))
`(~a ~b)
`(-> ~b ~a)))
This works because #() function literals are expanded into a form as follows:
(macroexpand `#(println % " World"))
=> (fn* [p1__2609__2610__auto__]
(clojure.core/println p1__2609__2610__auto__ " World"))
I still think this solution is rather ugly and prone to failure once you start doing more complicated things (e.g. using nested macros to generate your functions)
First, a couple of points:
Macros are simply functions that receive as input [literals, symbols, or collections of literals and symbols], and output [literals, symbols, or collections of literals and symbols]. Arguments are never functions, so you could never directly check the function the symbol maps to.
(call-special #(println % " World") "Hello") contains reader macro code. Since reader macros are executed before regular macros, you should expand this before doing any more analysis. Do this by applying (read-string "(call-special #(println % \" World\") \"Hello\")") which becomes (call-special (fn* [p1__417#] (println p1__417# "world")) "Hello").
While generally speaking, it's not obvious when you would want to use something when you should probably use alternative methods, here's how I would approach it.
You'll need to call macroexpand-all on a. If the code eventually becomes a (fn*) form, then it is guaranteed to be a function. Then you can safely emit (~a ~b). If it macroexpands to eventually be a symbol, you can also emit (~a ~b). If the symbol wasn't a function, then an error would throw at runtime. Lastly, if it macroexpands into a list (a function call or special form call), like (println ...), then you can emit code that uses the thread macro ->.
You can also cover the cases such as when the form macroexpands into a data structure, but you haven't specified the desired behavior.
a in your macro is just a clojure list data structure (it is not a function yet). So basically you need to check whether the data structure a will result is a function or not when it is evaluated, which can be done like show below:
(defmacro call-special? [a b]
(if (or (= (first a) 'fn) (= (first a) 'fn*))
`(~a ~b)
`(-> ~b ~a)))
By checking whether the first element of the a is symbol fn* or fn
which is used to create functions.
This macro will only work for 2 cases: either you pass it a anonymous function or an expression.

find about about the type of function parameters

can i somehow find all functions/macros that take a specific type of parameter ?
for example, what function accepts a Namespace object as parameter ?
(this is because i can create a namespace and store it in a var, but i don't know where i could use that var; what function might i pass that var to ?)
here is some code:
user=> (def working-namespace (create-ns 'my-namespace))
#'user/working-namespace
;i created a namspace and want to use it later
user=> (class working-namespace)
clojure.lang.Namespace
; out of curiosity i found out that "working-namespace" is a Namespace object
user=> (ns working-namespace)
nil
working-namespace=>
; but how do i switch to it ? this didn't do what i wanted...
user=> (refer working-namespace)
java.lang.ClassCastException: clojure.lang.Namespace cannot be cast to clojure.lang.Symbol (NO_SOURCE_FILE:0)
; this did not work either as my expectations
user=> (the-ns working-namespace)
#<Namespace my-namespace>
user=> (class (the-ns working-namespace))
clojure.lang.Namespace
; great, this gave me the same thing, a Namespace
hence the question: how do i use it dynamically (that's why i had put my namespace into a var) ? how do i get something useful for me from a var that points to a namespace ?
i can try look around for functions that make use of a Namespace object or that convert it to something else. i did and only found "intern". searching by hand not seems not that promising
what if i have this problem a million time ? is there an automated way to get me what i'm looking for without having to ask around each time ?
In Clojure 1.2 and previous function arguments dont have types. every function argument is an object. So the question really becomes "how do i find functions that will cast the object I pass them into this type. so searching for type hints will find some of them, though it wont get you everything. I wish it where more possible to answer this in general.
starting with 1.3 (current dev branch 9/2010) function paramerters and return types can have a defined type and will be passed/returned as that type instead of being cast to object and then cast on the other side. This drops one of the zeros from the exacution time of numerical functions with the important limitation that it only works for :static functions and only with direct calls (ie: not through map/reduce/filter/etc.) There is not a lot published on this change yet though it has the important breaking change that integers are no longer boxed by default and integer (actually Long) overflow throws an exception. you can read more here
(defn ^:static fib ^long [^long n]
(if (<= n 1)
1
(+ (fib (dec n)) (fib (- n 2)))))
so after 1.3 is released and widely adopted you will see code with more commonly defined types because they will offer a big speed benefit and then you will be able to find more functions by argument type though still not all of them.
At the same lecture where I learned about function argument types, Rich mentioned plans in the distant Clojure future (after 'Clojure in Clojure') about better support for exposing the compiler internals to tools such as IDEs. So there is hope that someday you will get a real answer to this question.
Dynamic languages make this slightly more difficult in practice and a lot harder in theory.
You already got a good answer from Arthur, so I'll only answer the "how do i get something useful for me from a var that points to a namespace ?". From (doc ns), note that it says unevaluated:
user=> (doc ns)
-------------------------
clojure.core/ns
([name docstring? attr-map? references*])
Macro
Sets *ns* to the namespace named by name (unevaluated), creating it
Now there's something you could do with in-ns if you want (the whole namespace object -> string -> symbol conversion is probably stupid, but enough to illustrate my point):
user=> (in-ns (symbol (str working-namespace)))
#<Namespace my-namespace>
my-namespace=>
I don't think you can do that without a lot of hackery in a dynamic language. If you want to now what function that take namespaces look at the documentation of the namespace stuff.
For example cleaning namespaces or reload them.
You wrote:
user=> (ns working-namespace)
nil
working-namespace=>
; but how do i switch to it ? this didn't do what i wanted...
But you did switch to the working-namespace namespace (that's why the prompt changed), so I'm not clear as to what "you wanted".
As I noted earlier, you need to present the ultimate problem are you trying to solve. It's entirely likely that messing with namespace objects won't be the solution.

can if be a proper function rather than a special form

I finally started learning functional languages (emacs lisp) and it makes explicit distinction between functions and special forms such as flow control , for example if.
Is there a fundamental/theoretical reason why special forms are distinct from functions? do any languages provide functional if?
Thanks
With eager evaluation the distinction is required, languages with lazy evaluation (i.e. Haskell) if et al. can be functions.
Eager evaluation: The function's arguments are evaluated before calling the function, and only the results are passed to the function.
Lazy evaluation: A function's arguments evaluated if and only if they are accessed.
If if was a normal function, then both its arguments—the then form and the else form—would both be evaluated before calling the if function, because that's the rule of function evaluation: evaluate all arguments to produce values, then provide that sequence of values as arguments to the function designated by the first symbol in the list.
Instead, with if what you want to do is evaluate exactly one of the then form and else form, not both. In order to suppress evaluation of one or the other, you need either a macro or a special form.
In languages like Emacs Lisp and Common Lisp, special forms are built-in language constructs. They have different evaluation rules that normal function calls. For normal function calls all arguments are evaluated. So, you can't write an IF as a normal function - the condition determines which clause gets evaluated. Also usually you can't write your own special forms - in Common Lisp there is no language construct for defining a special form (though individual implementations must have implemented the existing ones somehow. This leads to macros. With macros you can write a syntactic transformation that transforms one expression into another one. To be able to write IF as a macro, you need to have another conditional form, which you can use for the transformed code. Lisp provides conditionals as basic constructs. Let's assume COND is such a basic construct, then you could expand IF into a usage of COND.
MY-IF as a macro in Common Lisp:
(defmacro my-if (condition true-clause false-clause)
`(cond (,condition ,true-clause)
(t ,false-clause)))
So
(my-if (foo-p) 'one 'two)
gets expanded into
(cond ((foo-p) 'one)
(t 'two))
For completeness: there are no special forms in the Pico language for example, and if is a primitive function while Pico is inspired by Scheme and has eager evaluation by default.
In Scheme you could write
(define (true t f)
(t))
(define (false t f)
(f))
(define (function_if c t e)
(c t e))
and then
(function_if true (lambda () 'true) (lambda () 'false))
==> true
What makes this manageable in Pico is that you can define functional parameters that take functional arguments that are "automatically" delayed. This means that you don't have to do the wrapping inside lambdas yourself. Pico therefore has eager evaluation but with lazy evaluation on demand, bypassing the need for special forms.
So, in Scheme syntax with functional parameters you can encode booleans as:
(define (true (t) (f))
(t))
(define (false (t) (f))
(f))
Then function if becomes:
(define (function_if c (t) (e))
(c (t) (e)))
and
(function_if true 'true 'false)
==> true
As another example, the definition of the function and is (define (and p (q)) (p (q) false)).
Similarly you can define or, not, while, for, ... as functions, using the above encoding of booleans.
Short answer: No.
Long(er) answer: (if ...) requires that you control the evaluation order of the arguments. Lisp, being an eager language cannot do this in a function.
Workaround: do it in a macro:
(defmacro _if (cnd true false)
(let ( (gcond (gensym))
(gresp (gensym)))
`(let ( (,gcond ,cnd) ;`#quotes
(,gresp nil))
(and ,gcond (setf ,gresp (multiple-value-list ,true)))
(and (not ,gcond) (setf ,gresp (multiple-value-list ,false)))
(values-list ,gresp))))
For example:
[dsm#localhost:~]$ clisp -q
[1]> (defmacro _if (cnd true false)
(let ( (gcond (gensym))
(gresp (gensym)))
`(let ( (,gcond ,cnd) ;`#quotes
(,gresp nil))
(and ,gcond (setf ,gresp (multiple-value-list ,true)))
(and (not ,gcond) (setf ,gresp (multiple-value-list ,false)))
(values-list ,gresp))))
_IF
[2]> (_if (= 1 1) (+ 2 3) "bar")
5
[3]> (_if (= 1 2) (+ 2 3) "bar")
"bar"
[4]>
In Scala it's possible to model if with correct side-effect evaluation using call-by-name arguments.
def If[A](cond : Boolean, truePart : => A, falsePart : => A) = if (cond) truePart else falsePart
These feature can be used to model lots of new control structures as well.
IF could be a function in a functional language having call-by-name semantics (lazy evaluation), as in Lambda Calculus or Algol. In fact that is, I think, at the heart of the relationship between Turing Machines and Lambda Calculus as equivalent foundations for computing. However, in languages having side-effects (like assignments to variables) it is not much use, because when things happen is important.