Why does mis-spelling true/false not raise a compiler error in the online Elm editor (as opposed to elm-repl)? - elm

The following Elm program is supposed to print 10 if the mouse button is pressed and 20 if it is not pressed, but it always prints 20 (when running it at http://elm-lang.org/try) :
import Mouse
import Text (asText)
import Signal (map)
nextVal : Bool -> Int
nextVal down =
case down of
true -> 10
false -> 20
main = map asText (map nextVal Mouse.isDown)
The cause for this behaviour is a simple mis-spelling - if you replace true with True and false with False, everything works as expected.
But why don't I get a compiler error for this? I'd have expected something similar to the error message I get from the elm-repl: Could not find variable 'true'
UPDATE
In fact (as hinted at in the answer by #Apanatshka), this code also works in the REPL, so Elm behaves consistently.

I'd have to look into why elm-repl gives that error.
When I try this code on elm-lang.org/try it always gives 10. The code you've provided is valid Elm code. When you write a lowercase name in a case-of pattern, that name is considered a pattern variable. It will match anything and bind what it matches to that name. So your nextVal function will try to match a boolean with the given patterns, in the order given. It starts with the first pattern, which is a single pattern variable, therefore it always matches. There it stops searching, because the pattern matches, therefore 10 is always returned.
Perhaps you would prefer to use an if-then-else?
nextVal down =
if down
then 10
else 20
One last thing: When you're just matching an enumeration like Bool it probably doesn't seem useful to have these pattern variables. Just to show that it can be useful, I wrote a little example with a singly linked list:
type SLList a =
Cons a (SLList a)
| Nil
-- a list of 1,2,3 would look like: Cons 1 (Cons 2 (Cons 3 Nil))
removeSurroundingElements : SLList a -> SLList a
removeSurroundingElements l =
case l of
Nil -> Nil
Cons _ Nil -> l -- `_` means ignore
Cons _ (Cons _ Nil) -> l
Cons e1 (Cons e2 (Cons e3 tail)) ->
Cons e2 (removeSurroundingElements tail)
-- removeSurroundingElements (Cons 1 (Cons 2 (Cons 3 Nil))) == Cons 2 Nil
-- removeSurroundingElements (Cons 1 (Cons 2 (Cons 3 (Cons 4 (Cons 5 (Cons 6 Nil))))))
-- == Cons 2 (Cons 5 Nil)

Related

Sum of numeric elements in a nested list LISP

Return the SUM of numeric elements in a nested list using LISP. If there are no numeric elements return an empty list/NIL
Examples:
(6 3 -2 5 (4 2 -3) 4) should return 19
(1 2 3 (-4 5) a b c) should return 7
Asking other people to do your homework for you is almost never a good way of learning anything.
But here's an answer, which is written in a Lisp (Racket) and which does show how you ought to go about solving this problem, and also (I think) demonstrates some nice ways of thinking about problems like this ... but which you almost certainly can't cut and paste.
Note that this does not quite agree with the requirements given: which is supposed to return a non-numeric value for a list with no numbers in it. That breaks a recursive algorithm like this, since the empty list is a list with no numbers in it. So this does something more sensible. Making this answer implement the requirements is left as an exercise to the student.
(define (sum-nested-list l)
(let sum-nested-list-loop ([thing l]
[running-total 0])
(match thing
['()
;; We're done if we've run out of list
running-total]
[(list* (? number? x) r)
;; A list whose first element is a number: add it to the running total
;; and carry on on the rest of the list
(sum-nested-list-loop r (+ running-total x))]
[(list* (? list? x) r)
;; A list whose first element is a nested list: recurse into the
;; nested list
(sum-nested-list-loop r (sum-nested-list-loop x running-total))]
[(list* _ r)
;; A list whose first element is not a number or a nested list:
;; carry on on the rest of the list
(sum-nested-list-loop r running-total)]
[_
;; Not a list at all: explode
(error 'sum-numeric-list "what?")])))
(defun flat-sum (tree)
(let ((count 0))
(tree-equal tree tree :test (lambda (left right)
(if (numberp left)
(incf count left) t)))
count))
1> (flat-sum '(1 2 3 (-4 5) a b c))
7

Distinguishing Bound from Unbound Variables

I'm trying to write a macro, called different, to test whether two user-provided arguments are provisionally eq, where the arguments may be bound or unbound. But I'm getting lost in the possibilities (and perhaps logic). The following seems to work, but needs enhancement (including avoiding variable capture and multiple evaluation):
(defmacro different (item1 item2)
`(not (eq (if (boundp ',item1) ,item1 ',item1)
(if (boundp ',item2) ,item2 ',item2))))
The basic idea is to look for any unbound variable, quote it, and then see if that is eq to the value of the other variable. (The goal is to save the end-user from having to decide when to quote arguments, since bound variables are otherwise marked.)
So now:
if x is unbound and y is bound to 'x, or
y is unbound and x is bound to 'y
(different x y) => NIL
if x is unbound and y is bound to 'z, or
y is unbound and x is bound to 'z
(different x y) => T
The main problem is that item1 or item2 can be designators for arbitrary lisp objects (in which case equalp would be substituted for eq). For example:
(defparameter x 3)
(different x 3) => NIL (since they are equalp)
(defparameter x '(a b c))
(different x (c b a)) => T (where (c b a) gets quoted)
Can this be factored into the macro, and can the if statements be brought outside the backquote?
There are only six cases to deal with
Here is a mapping of what is to be done:
For b ≡ bound symbol
For u ≡ unbound symbol
For e ≡ any other value
b b -> eq
b u -> equalp
u u -> equalp
e e -> equalp
e u -> ERROR (makes no sense)
e b -> equalp
Hopefully this helps you organize your branching logic. I like to pull some paper and work through branching when I get an explosion like this. Normally it is possible to reduce it using predicate calculus, or come up with another representation that has less branches.

While loops working mechanism of a program in Scheme

DrRacket user.
I'm struggling to understand how this program works.I wrote it myself and it does what it must but I can't understand how.
I define while loops as:
(define (while test body)
(if (test)
(begin
(body)
(while test body))
(void)))
Now I need to write a program that applies the given procedure to each element of a mutable list.
Here what I wrote:
(define (mlist-map-while f x)
(while (lambda() (not (null? x)))
(lambda ()
(set-mcar! x (f (mcar x)))
(set! x (mcdr x))))
(void))
So, defining
list1 (mlist 1 2 3)
and applying
(mlist-map-while (lambda (x) (+ x 1)) list1)
we get '(2 3 4).
The thing that I don't understand is how the first element of the list stays in it, because if it's done how I wrote here
(set! x (mcdr x))
the first procedure that sets -mcar! must be useless and be overlapped with the second. Like in this example:
(define list1 (mlist 1 2 3))
(set-mcar! list1 9)
(set-mcdr! list1 (mcdr list!))
and we lack the first element, but this program somehow leaves it in and gives the desired output. I would like to know how it works and whether there is another way of traversing the given list.
There is a big difference between set-cdr! abd set!. The first alters the pair's cdr pointer, while the latter alters the binding, thus what the name should point to.
In your mlist-map-while the variable x alters the car, then changes what x represents, to be the cdr of x. It never changes the cdr so your binding list1 always points to the first pair while x points to the first, then second, etc...
Thus it's more like this:
(define list1 (mlist 1 2 3))
(define list1-ref list1) ; variable pointing to the same value as list1
(set-mcar! list1-ref 9) ; set-car! changes the pair
(set! list1-ref (mcdr list)) ; set! updates what list1-ref points to
list1 ; ==> (9 2 3)
list-ref ; ==> (2 3)
You can iterate over a list in the same fashion without using set!, with recursion:
(define (fold function init lst)
(if (null? lst)
init
(fold function
(function (car lst) init)
(cdr lst))))
(fold + 0 '(1 2 3)
; ==> 6
(fold cons '() '(1 2 3))
; ==> (3 2 1)
Notice that here we recurse and change what lst is, to be the cdr. Every recursion has its own lst, which is not to be confused with the caller's own. It ends up doing the same as set! in your example, without mutation.

What does _ mean in Elm?

I'm looking at the zip example on http://elm-lang.org/examples/zip and I had a question about what exactly the _ means in Elm.
zip : List a -> List b -> List (a,b)
zip xs ys =
case (xs, ys) of
( x :: xs', y :: ys' ) ->
(x,y) :: zip xs' ys'
(_, _) ->
[]
My hunch is that it means "everything else" but does that mean any valid value? What if there is no value?
_ is used to match anything where you don't care about the value, so it's commonly used to match the "everything else" case.
In your example code (_, _) will match any tuple with 2 values in it. Note that it could also be replaced with just _ since you end up not caring about either value. A more illustrative example would be where you care about one value from the tuple but not the other, for example the implementation of fst in the core package
fst : (a,b) -> a
fst (a,_) =
a
We don't care about the second value in the tuple, so it just matches with an _ in that position.
There is no null or undefined in Elm, so you don't have to worry about there being "no value" (if something would have no value, the Maybe type is used).

How to remove an element from a list without using remove function in LISP

(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1))
(if (!= x e)
((my_append e list2 )
(setf y cdr(list1))
(my_remove(e y list2)))
((setf y cdr(list1))
(my_remove(e y list2))
)))))
I am trying to write a function to remove an element from a list but i am getting an error that "It should be lambada function" and I don't know that my code is correct or wrong.
Problems with your code
There are a few problems with your code. First, let's look at it with standard indentation
(defun my_remove(e list1 list2)
(if (null list1)
nil
((setf x car(list1)) ; (i)
(if (!= x e)
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
((setf y cdr(list1)) ; (v)
(my_remove(e y list2))))))) ; (vi)
Each of the marked lines has a problem. The syntax for a function call in Lisp is
(function argument…)
That means that in your line (i), you're trying to call a function named (setf x car(list1)) with an argument (if (!= x e) …). Of course, that's not the name of a function, and I suspect that even if it was, you didn't want to call it with the argument (if (!= x e) …). Similarly
(setf x car (list1))
Is trying to to set x to the value of the value of a variable car (and there isn't one), and then assign a new value to the place (list1). Since the syntax for a function call is (function argument…), you want instead:
(setf x (car list1))
If you're trying to sequence forms, you might consider using cond, in which you can provide multiple forms, or progn (see In Common Lisp, why do multi-expression bodies of (if) statements require (progn)?).
For instance, instead of
((my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
you probably want
(progn
(my_append e list2 ) ; (ii)
(setf y cdr(list1)) ; (iii)
(my_remove(e y list2))) ; (iv)
You'll have some problems with that, too, though. In (iii) and (iv), you'll need to use (cdr list1) and (my_remove e y list2), as discussed above, but you also have the problem that you're evaluating (ii) and (iii), but you're discarding the value.
A simplified approach
I think it might be to your benefit if you think about a simple definition of my-remove. In general, a list is either the empty list () or a cons cell whose car is the first element of the list and whose cdr is the rest of the list. You can use a definition like this, then:
remove(x,list)
if list is empty, then return list (it's empty, so it certainly doesn't contain x)
if list is not empty, then
if the first element of the list is x, then return remove(x,rest(list))
else, the first element of the list is not x, so return a new list whose first element is the first element of list, and whose rest is remove(x,rest(list)).
In code, that looks like:
(defun my-remove (element list)
(if (endp list)
list
(if (eql element (first list))
(my-remove element (rest list))
(list* (first list)
(my-remove element (rest list))))))
CL-USER> (my-remove 1 '(1 2 3 1 2 3))
(2 3 2 3)
Those nested ifs look a bit ugly, and you might want to use cond here, even though you don't need the multiple expression bodies that it permits:
(defun my-remove (element list)
(cond
((endp list)
list)
((eql element (first list))
(my-remove element (rest list)))
(t
(list* (first list) (my-remove element (rest list))))))
Since a cond clause with no body whose test form evaluates to true returns the value of the test form, you can even make that last clause a bit simpler:
(defun my-remove (element list)
(cond
((endp list) list)
((eql element (first list)) (my-remove element (rest list)))
((list* (first list) (my-remove element (rest list))))))