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))
Related
I am beginner in Haskell .
The convention used in function definition as per my school material is actually as follows
function_name arguments_separated_by_spaces = code_to_do
ex :
f a b c = a * b +c
As a mathematics student I am habituated to use the functions like as follows
function_name(arguments_separated_by_commas) = code_to_do
ex :
f(a,b,c) = a * b + c
Its working in Haskell .
My doubt is whether it works in all cases ?
I mean can i use traditional mathematical convention in Haskell function definition also ?
If wrong , in which specific cases the convention goes wrong ?
Thanks in advance :)
Let's say you want to define a function that computes the square of the hypoteneuse of a right-triangle. Either of the following definitions are valid
hyp1 a b = a * a + b * b
hyp2(a,b) = a * a + b * b
However, they are not the same function! You can tell by looking at their types in GHCI
>> :type hyp1
hyp1 :: Num a => a -> a -> a
>> :type hyp2
hyp2 :: Num a => (a, a) -> a
Taking hyp2 first (and ignoring the Num a => part for now) the type tells you that the function takes a pair (a, a) and returns another a (e.g it might take a pair of integers and return another integer, or a pair of real numbers and return another real number). You use it like this
>> hyp2 (3,4)
25
Notice that the parentheses aren't optional here! They ensure that the argument is of the correct type, a pair of as. If you don't include them, you will get an error (which will probably look really confusing to you now, but rest assured that it will make sense when you've learned about type classes).
Now looking at hyp1 one way to read the type a -> a -> a is it takes two things of type a and returns something else of type a. You use it like this
>> hyp1 3 4
25
Now you will get an error if you do include parentheses!
So the first thing to notice is that the way you use the function has to match the way you defined it. If you define the function with parens, you have to use parens every time you call it. If you don't use parens when you define the function, you can't use them when you call it.
So it seems like there's no reason to prefer one over the other - it's just a matter of taste. But actually I think there is a good reason to prefer one over the other, and you should prefer the style without parentheses. There are three good reasons:
It looks cleaner and makes your code easier to read if you don't have parens cluttering up the page.
You will take a performance hit if you use parens everywhere, because you need to construct and deconstruct a pair every time you use the function (although the compiler may optimize this away - I'm not sure).
You want to get the benefits of currying, aka partially applied functions*.
The last point is a little subtle. Recall that I said that one way to understand a function of type a -> a -> a is that it takes two things of type a, and returns another a. But there's another way to read that type, which is a -> (a -> a). That means exactly the same thing, since the -> operator is right-associative in Haskell. The interpretation is that the function takes a single a, and returns a function of type a -> a. This allows you to just provide the first argument to the function, and apply the second argument later, for example
>> let f = hyp1 3
>> f 4
25
This is practically useful in a wide variety of situations. For example, the map functions lets you apply some function to every element of a list -
>> :type map
map :: (a -> b) -> [a] -> [b]
Say you have the function (++ "!") which adds a bang to any String. But you have lists of Strings and you'd like them all to end with a bang. No problem! You just partially apply the map function
>> let bang = map (++ "!")
Now bang is a function of type**
>> :type bang
bang :: [String] -> [String]
and you can use it like this
>> bang ["Ready", "Set", "Go"]
["Ready!", "Set!", "Go!"]
Pretty useful!
I hope I've convinced you that the convention used in your school's educational material has some pretty solid reasons for being used. As someone with a math background myself, I can see the appeal of using the more 'traditional' syntax but I hope that as you advance in your programming journey, you'll be able to see the advantages in changing to something that's initially a bit unfamiliar to you.
* Note for pedants - I know that currying and partial application are not exactly the same thing.
** Actually GHCI will tell you the type is bang :: [[Char]] -> [[Char]] but since String is a synonym for [Char] these mean the same thing.
f(a,b,c) = a * b + c
The key difference to understand is that the above function takes a triple and gives the result. What you are actually doing is pattern matching on a triple. The type of the above function is something like this:
(a, a, a) -> a
If you write functions like this:
f a b c = a * b + c
You get automatic curry in the function.
You can write things like this let b = f 3 2 and it will typecheck but the same thing will not work with your initial version. Also, things like currying can help a lot while composing various functions using (.) which again cannot be achieved with the former style unless you are trying to compose triples.
Mathematical notation is not consistent. If all functions were given arguments using (,), you would have to write (+)((*)(a,b),c) to pass a*b and c to function + - of course, a*b is worked out by passing a and b to function *.
It is possible to write everything in tupled form, but it is much harder to define composition. Whereas now you can specify a type a->b to cover for functions of any arity (therefore, you can define composition as a function of type (b->c)->(a->b)->(a->c)), it is much trickier to define functions of arbitrary arity using tuples (now a->b would only mean a function of one argument; you can no longer compose a function of many arguments with a function of many arguments). So, technically possible, but it would need a language feature to make it simple and convenient.
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.
I am writing a simple member function that returns the value associated with that member. The first line of the conditional (to test if the first value is the one we're looking for) works fine, but the recursive part (to test parts of the list that are further along) returns an error every time.
Here is my function:
(defun mem (prop L)
(cond
((eq (caar L) prop) (print cadar L)))
(t (mem (prop (cdr L)))))) // error is on this line!
So, if I enter
(mem `i `((i 1) (j 2)))
it correctly returns 1. However, if I enter
(mem `j `((i 1) (j 2)))
it returns an error that "function prop is undefined."
How do I let the program know that prop isn't a function, but is just an input parameter?
This is my first lisp program, so I'm assuming the answer is incredibly simple, but I have tried many things and have yet to succeed.
The problem in particular is the snippet: (prop (cdr L)). This tries to call prop, passing it (cdr L). To pass it as an argument to mem, simply leave out the extra parentheses: (mem prop (cdr L)).
If you're having a problem figuring out where to put parentheses in general, note that Lisp syntax is very similar to mathematical syntax for functions, except the function goes on the inside of the parentheses (and you use spaces instead of commas, but that isn't a problem here). For example, written in mathematical notation, you have: mem(prop(cdr(L))), instead of mem(prop, cdr(L)).
Other Issues
It looks like you have an extra parentheses after the first branch of the cond, which ends it early. Use an editor/IDE with parentheses matching to catch this sort of error. Emacs does it, as does DrRacket. The former can be used with Common LISP via SLIME (search the web for set-up instructions for your platform), while the latter readily supports Scheme.
The semicolon (";") is the comment character used in most LISPs.
print isn't necessary for this function, and (depending on its behavior) may be incorrect. In some LISPs (e.g. Common LISP), it returns its argument, but in others it may return nil or the instance of some void type.
Quasiquote (aka backquote, backtick) is also unnecessary. Quasiquote lets you quote some symbols, while others (those prefixed with a comma) are replaced with their values. Since you don't need substitution in the quoted expressions, a plain quote will work: (mem 'j '((i 1) (j 2))).
For readability, insert more whitespace between closing and opening parentheses.
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 *
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.