Re: a bunch of questions about syntax
thanks for your answers, Alex On Sun, Jan 29, 2017 at 9:48 AM, Alexander Burger wrote: > > > >(if (testSomething) (doSomething1) (doSomething2) (doSomething3)) > > ... > > but this also means the only way to indicate several executable > expressions > > in the "then-clause" is to surround them between parens, i.e. (if (= 2 > 2) > > ((print "equal") (print "2")) (print "not equal") (print "not 2")) I > > No. This gives a crash (try it, and think about why ;). > I tried and it crashes with a segmentation fault, I was thinking about what could be the reason and my guess is it is related with 'eval' function. I think when the body of "if" function tries to eval the any2 expression it fails with sementation fault if it is a list of lists, that is, the first item of any2 expression is a list: (eval 1) -> 1 (eval (1)) -> (1) (eval ((1))) segmentation fault My guess is eval tries to evaluate its parameter, thus when being a number it evaluates to itself and an atom evaluates to its value: (setq A 1) (eval A) -> 1 (eval B) --- B is not defined But when the parameter to evaluate is a list, eval tries to evaluate the list which means to apply the function call represented by the list, with special case of lists of numbers (de f (X) (+ X 1)) (eval (f 1)) -> 2 # eval tries to evaluate the list viewed as a function call so it applies function f to parameter 2 and gets the returned value as the result of eval (eval (1 2)) -> (1 2) # the same as above but exploiting the special treatment picolisp give to list of numbers in order to avoid quoting it The problem appears when you pass eval a list of lists (or a list with a first item which is also a list), in this case eval tries to evaluate but doen't know how to eval a item list, it could be a function call because it is not an atom. Using the analogy of stack when eval gets a simple list it pops the first item which being an atom means it must be a function name so two possible cases it's a defined function or it is not defined, if it is defined but it's not a function but it also fails with segmentation fault because you cannot apply an atom if it's not a function (and evaluating a list means it must be a function call --or a list of numbers--) (de f (X) (* X X)) (setq A 1) (eval (f 2)) -> 4 (eval (A 2)) --- segmentation fault (eval f) --- X undefined (eval 'f) -> ((X) (* X X)) (eval (f)) -> NIL # strangely in this case it doesn't say X undefined but returns NIL The problem seems to be only when eval expects an atom to be a function or an undefined symbol and what it gets is an defined atom which is not a function symbol: (eval B) -> NIL (eval (B)) --- B undefined (eval (B 1)) --- B undefined (eval ((B))) --- B undefined (eval ((B 1))) --- B undefined (setq B 2) (eval B) -> 2 (eval (B)) --- segmentation fault (eval (B 1)) --- segmentation fault (eval ((B))) --- segmentation fault (eval ((B 1))) --- segmentation fault Also eval evaluates recursively the list passed as arguments (de g (X) (+ X 1)) (de f (X) 'g) (eval ((f 99) 2 )) -> 3 So my conclusion is eval always expect a list to be a valid function call (or a list of numbers) and if it is not then fails with segmentation fault. And the reason for "if" to fail in a similar way is it tries to eval the "then-clause" (any2) If so what I don't understand is why to cause a segmentation fault, I think it could easily avoid if eval phase in REPL simply detect a first item in a list being a defined atom but not a function and throw an error (in a similar way of "not defined" errors in previous examples) or even even evaluating the atom to its value when it detects it is not a function (even being the first item in a list). What I mean is maybe a desiderable behaviour of eval would be: (setq A 1) (de f (N) (+ N 1)) (eval A) -> 1 (eval (f 1)) -> 2 (eval (A 2)) --- A is not a function # case 1, eval knows it is not a function (eval (A 2)) -> 1 # case 2, even when it seems a function call since A is not a function but a defined symbol resolve to its value (eval ((A))) -> 1 # case 2, but could also be implemented as case 1 too Is it my reasoning right? or maybe I'm saying a nonsense? Anyway I see the segmentation fault messages includes some numbers, are they anyhow setted by picolisp or are they totally system dependent? [1]863 segmentation fault ./pil + ^ ^^^ |__| this numbers regards
Re: a bunch of questions about syntax
On Sat, Jan 28, 2017 at 09:55:14PM +0100, pd wrote: > Thank you Alex for your patience, I see I have a severe confussion about > how picolisp manages lists No problem! It is good to discuss this here, as it may help others too. > let's start by the begining... as far as I know (f a b 4) is just a list > equivalent to (f . (a . (b . (4 . NIL and the fact being also a > function call to function f applying parameters a b 4 is just a matter of > "convention", simply when picolisp evals a list with a first item not being > a number it supposes it's a function call and tries to evaluate first item > (it doesn't matter if first item is a symbol or another list, it gets > evaluated) which is supposed to be evaluated to a function value That's right. > With this point of view I understand what you mean when saying (f 1 a b c) > is just the same as (f 1 . (a b c)) and thus you can view a, b, c as a list Yes. > so you can describe this funcion as (f num . 'lst), ok, but also I think > ... > you could describe the function f also as (f . 'lst) . The only difference Yes, but without the quotes. As a function reference (f num . 'lst) is impossible, as the quote indicates evaluation which is not handled by PicoLisp this way. > But if you describe a function like (g num 'lst) is a quite different thing > because you are expecting two arguments the first one being a number and > the second being a list (of unlimited number of items), really all Yes. > functions described have an unlimited number of arguments but function g > packs all arguments but the first in a list. No. This is not done by 'g'. This function *expects* a list after evaluating its second argument. > >(if (testSomething) (doSomething1) (doSomething2) (doSomething3)) > ... > but this also means the only way to indicate several executable expressions > in the "then-clause" is to surround them between parens, i.e. (if (= 2 2) > ((print "equal") (print "2")) (print "not equal") (print "not 2")) I No. This gives a crash (try it, and think about why ;). The "then" clause must be a single expression. Typicaley you use 'prog' if you need to call more than one expression here. > appreciate here an absence of symmetry, you must pack all exe expressions That's right. > why not to define and describe function if in a symmetrical way as (if > 'any prg1 prg2) even when not obeying parens economy? (sure there is a > good reason to do it that way simply I'm not able to see) If 'if' were specified this way, it would lose its simplicity because you always need additional nesting for the "then" clause. For more complex conditional expressions, we use 'cond' instead of 'if'. > - two functions f described this way: > >(f num . lst) >(f num1 num2) > > then the list (f 1 2) is a valid call for both functions, the first f will > bind first parameter to numer 1 and second parameter to list (2) (all > remaining parameters as a list) while the second f will bind 1 to num1 and > 2 to num2 (descarding empty list NIL). Correct. > My confusion here is picolisp must > do two pops to bind parameters for a first f function call but three pops > to bind parameters for a second f function call. How discriminate picolisp > between each cases? I suppose the answer is function definition: > > first f defined as (de f (X . Rest) (...) ) > second f defined as (de f (X Y) (...) ) Exactly. The interpreter finds either (X . Rest) or (X Y) when evaluating (f 1 2), so it knows what to do. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: a bunch of questions about syntax
Thank you Alex for your patience, I see I have a severe confussion about how picolisp manages lists let's start by the begining... as far as I know (f a b 4) is just a list equivalent to (f . (a . (b . (4 . NIL and the fact being also a function call to function f applying parameters a b 4 is just a matter of "convention", simply when picolisp evals a list with a first item not being a number it supposes it's a function call and tries to evaluate first item (it doesn't matter if first item is a symbol or another list, it gets evaluated) which is supposed to be evaluated to a function value With this point of view I understand what you mean when saying (f 1 a b c) is just the same as (f 1 . (a b c)) and thus you can view a, b, c as a list so you can describe this funcion as (f num . 'lst), ok, but also I think you could describe the function f also as (f . 'lst) . The only difference is that using the latter you are only interested in remark you pass to f a sequence of symbols (which form a list) while using the former description you are interested in remark the first symbol in the sequence is supposed to be a number and also it is not evaluated. But if you describe a function like (g num 'lst) is a quite different thing because you are expecting two arguments the first one being a number and the second being a list (of unlimited number of items), really all functions described have an unlimited number of arguments but function g packs all arguments but the first in a list. I think I get the point, but what confuses me is when you say On Sat, Jan 28, 2017 at 8:31 AM, Alexander Burger wrote: > > From this point of view my question is about the difference of using or > > > not using dot when describing a function, for example, take the if > > > description: > > > > > > (if 'any1 any2 . prg) -> any > > > > > > Would the description below describe the same function? > > > > > > (if 'any1 any2 prg) -> any > > A typical call of 'if' could be > >(if (testSomething) (doSomething1) (doSomething2) (doSomething3)) > > where > >any1 is the result of evaluating (testSomething) >any2 is (doSomething1) >prg is ((doSomething2) (doSomething3)) > > Perhaps it helps understanding if we remember that > >(if (testSomething) (doSomething1) (doSomething2) (doSomething3)) > > is the same as > >(if (testSomething) (doSomething1) . ((doSomething2) (doSomething3))) > > > If 'if' were specified as in the second case (if 'any1 any2 prg), then we > would > need to call it as > >(if (testSomething) (doSomething1) ((doSomething2) (doSomething3))) > > to match the spec (if 'any1 any2 prg) and get the same bindings. > > but this also means the only way to indicate several executable expressions in the "then-clause" is to surround them between parens, i.e. (if (= 2 2) ((print "equal") (print "2")) (print "not equal") (print "not 2")) I appreciate here an absence of symmetry, you must pack all exe expressions in a list for "then-clause" but you can't do it for "else-clause" [in fact I think it will fail if you do that in a "then-clause" like (if T 1 ((print "ups") (print "error"))) ] why not to define and describe function if in a symmetrical way as (if 'any prg1 prg2) even when not obeying parens economy? (sure there is a good reason to do it that way simply I'm not able to see) this way you always write prgs inside a list whatever being in then-clause or an else-clause i.e. (if (> a b) ((print "a greater")) ((print "b greater or equal"))) > > > > (if T 3 4) # > invalid because 4 is a number not a prg (a list) > > Yes, but the prg is (4), not 4. > I guess you say that because using the "stack" simil you used in previous email, when you pop first item it remais (T 3 4) when you pop again it remains (3 4) and with next pop which remains is (4) I think my confusion is due to the lack of one more pop to get 4 rather than (4) , if the answer is "because prg indicates its a list, if you want to indicate a number you should use num instead" then my confusion is like this: - two functions f described this way: (f num . lst) (f num1 num2) then the list (f 1 2) is a valid call for both functions, the first f will bind first parameter to numer 1 and second parameter to list (2) (all remaining parameters as a list) while the second f will bind 1 to num1 and 2 to num2 (descarding empty list NIL). My confusion here is picolisp must do two pops to bind parameters for a first f function call but three pops to bind parameters for a second f function call. How discriminate picolisp between each cases? I suppose the answer is function definition: first f defined as (de f (X . Rest) (...) ) second f defined as (de f (X Y) (...) ) is it ok? thanks a lot and forgive my insistence ;-)
Re: a bunch of questions about syntax
On Sat, Jan 28, 2017 at 02:35:09AM +0100, pd wrote: > sorry, I accidentally sent an incomplete message, here's the complete one > ... > >> > >> BTW, I thought again about the terminology of "list" versus "cons pairs" > >> and > >> plain "cells". "list" is a rather unprecise term, I feel it is not > >> limited to "a > >> chain of cells with NIL at the end". I use "list" for any sequence of > >> cells (as > >> opposed to other structures like "tree", "graph" or "set"). These include > >> also > >> e.g. "circular lists" like (1 2 3 .), which have no NIL at the end (in > >> fact, no > >> end at all). > >> > > Ok, so from this point of view every cons pair is a list even those with a > > dotted pair in the tail No, definitely not. I would not call (3 . 4) a list. Still, as I said, "list" is a rather unprecise term. Some people use the term "proper list" for a NIL-terminated list. > > I mean, with a NIL ending list you have an empty list condition (NIL) but > > how do you know a non-NIL ending list is empty? and since most functions No. Only the atom 'NIL' is the empty list. > > condition to finish processing the list I think it would be interesting to > > discriminate between those two kinds of lists. I think it does not matter. At least it is not very important. Every function in Lisp is free to treat its arguments as it likes. The PicoLisp interpreter doesn't care very much. Most list-processing functions do not check for NIL at the end, but whether the item is atomic or not In C: while (isCell(cdr(x = cdr(x In Asm: ld X (X CDR) # Args atom (X CDR) # more than one left? while z # Yes > > what about these two? are they equivalent? > > > > (f num lst) -> num > > (g num . lst) -> num No. 'f' takes two argument (supposed to evaluate to a number and a list), while 'g' takes an unlimited number of arguments (the first supposed to be a number after evaluation, the rest unspecified). > > of course it's the function body which determines the "type" of > > parameters, if the body applies a parameter to a function expecting a > > number, that parameter's type must be a number and not a symbol or list or > > the function call in the body will fail, but you use a notation for Right. > > describing functions just to help users know what kind of parameter you > > must provide, that's the reason to use that list of meaningful words, type > > is not enforced (not possible) but suggested to user using the function, > > right? Exactly. > > From this point of view my question is about the difference of using or > > not using dot when describing a function, for example, take the if > > description: > > > > (if 'any1 any2 . prg) -> any > > > > Would the description below describe the same function? > > > > (if 'any1 any2 prg) -> any A typical call of 'if' could be (if (testSomething) (doSomething1) (doSomething2) (doSomething3)) where any1 is the result of evaluating (testSomething) any2 is (doSomething1) prg is ((doSomething2) (doSomething3)) Perhaps it helps understanding if we remember that (if (testSomething) (doSomething1) (doSomething2) (doSomething3)) is the same as (if (testSomething) (doSomething1) . ((doSomething2) (doSomething3))) If 'if' were specified as in the second case (if 'any1 any2 prg), then we would need to call it as (if (testSomething) (doSomething1) ((doSomething2) (doSomething3))) to match the spec (if 'any1 any2 prg) and get the same bindings. > > (if T 3 (print "no")) # valid > > (if (< 2 2) 'x (print "yeah"))# valid > > (if T 3 4)# invalid > > because 4 is a number not a prg (a list) Yes, but the prg is (4), not 4. > > (if NIL (print "then") (print "else") (print "finally")) # a doubt here, > > ># I > think it's invalid because two executable expressions are two lists not one > prg (one list of executable expressions) No, it is perfectly valid. (print "then") is the "then" part, an 'exe' ((print "else") (print "finally")) is the "else" part, a 'prg' > (if (really?) (print (car *Glist)) NIL) # invalid because you cannot use > a NIL value as "else" return, you need to supply a executable expressions No, perfectly valid. The 'prg' is (NIL). Remember how a 'prg' is executed: Each expressions is evaluated, one after the other, and the result of the last one is the result of the whole 'prg'. The last expression evaluated here is NIL, so the result is NIL. > (if (really?) (print (car *Glist)) (NIL)) # so you must rewrite the This would crash, as the 'prg' is ((NIL)), thus the last expression is (NIL), and NIL is not a function. > The primary data types: > >- num - Number >- sym - Symbol >- lst - List > ... >- any - Anything: Any data type > It's not a matter of type endorsement but a kind of typ
Re: a bunch of questions about syntax
sorry, I accidentally sent an incomplete message, here's the complete one On Sat, Jan 28, 2017 at 1:51 AM, pd wrote: > Thanks again for your explanations Alex, still some comments... > > On Fri, Jan 27, 2017 at 8:16 AM, Alexander Burger > wrote: > >> >> >> BTW, I thought again about the terminology of "list" versus "cons pairs" >> and >> plain "cells". "list" is a rather unprecise term, I feel it is not >> limited to "a >> chain of cells with NIL at the end". I use "list" for any sequence of >> cells (as >> opposed to other structures like "tree", "graph" or "set"). These include >> also >> e.g. "circular lists" like (1 2 3 .), which have no NIL at the end (in >> fact, no >> end at all). >> > > Ok, so from this point of view every cons pair is a list even those with a > dotted pair in the tail > > But I think it's interesting to distinguish between two different kind of > lists, those having a NIL symbol in last cell CDR (let's say ending in NIL > symbol) and with a non NIL in las cell CDR (those ending in a symbol not > NIL) just because of almost every function dealing with lists assume they > belong to NIL-ending kind. > > I mean, with a NIL ending list you have an empty list condition (NIL) but > how do you know a non-NIL ending list is empty? and since most functions > dealing with lists have a recursive pattern looking for an empty list > condition to finish processing the list I think it would be interesting to > discriminate between those two kinds of lists. > > For example, let's define f as: > > (de f (L) (print (car L)) (if (<> NIL (cdr L)) (f (cdr L > > then f is well defined for NIL ending lists but fails with non-NIL ending > lists > > > > >> > but when describing functions ' is a notation mark with a >> > semantic, what is the semantic of dot notation mark when used in formal >> > parameters in function description? >> > >> > I mean, you have these two notations for functions: >> > >> > - (dbs+ 'num . lst) >> > >> > - (delete 'any 'lst) -> lst >> > >> > are they applied the same? with the same kind of parameters? >> >> The functions behave differently. (dbs+ 'num . lst) means that the the >> function >> takes an unlimited number of arguments, where only the first one is >> evaluated, >> while (delete 'any 'lst) takes two evaluated arguments. > > > what about these two? are they equivalent? > > (f num lst) -> num > (g num . lst) -> num > > >> >> > evaluate to a number and rest of parameters will be bound to Z, so you >> call >> > this function like (dbs+ 4 a b c) , what notation will you use to >> express >> > you have to pass a list as parameter to a function? maybe (dbs+ 'lst) >> ? I >> >> These function definitions say nothing about the types of the arguments >> like >> number, list etc. This is determined by the behavior of the function's >> body. >> >> > of course it's the function body which determines the "type" of > parameters, if the body applies a parameter to a function expecting a > number, that parameter's type must be a number and not a symbol or list or > the function call in the body will fail, but you use a notation for > describing functions just to help users know what kind of parameter you > must provide, that's the reason to use that list of meaningful words, type > is not enforced (not possible) but suggested to user using the function, > right? > > so a function described as(f 'num 'num) informs that function f > expects two parameters being numbers and since parameters are evaluated > it's the value what is expected to be numers, so you can call f as (f 1 2) > or (f a b) or even (f (x y z) 3) provided that values of symbols a and b > are numbers and the result of x function call (x y z) returns a number but > sure you cannot call f as (f (1 2)) or (f 'x 4) > > From this point of view my question is about the difference of using or > not using dot when describing a function, for example, take the if > description: > > (if 'any1 any2 . prg) -> any > > Would the description below describe the same function? > > (if 'any1 any2 prg) -> any > > Even more, having into account notation used for describing functions I > know: > > any - Anything: Any data type > prg - Prog-Body: A list of executable expressions (run) > > so from description of function "if" which is "Conditional execution: If > the condition any1 evaluates to non-NIL, any2 is evaluated and returned. > Otherwise, prg is executed and the result returned." I undestand the > "then" clause is any2 which gets evaluated when evaluated any1 is T and > also it could be any type of value while prg is the "else" clause being > evaluated only if evaluation of any1 returns NIL and also it is a list of > executable expressions, from this I understand the following is a list of > valid and invalid if function calls: > > (if T 3 (print "no")) # valid > (if (< 2 2) 'x (print "yeah"))# valid > (if T 3 4)
Re: a bunch of questions about syntax
Thanks again for your explanations Alex, still some comments... On Fri, Jan 27, 2017 at 8:16 AM, Alexander Burger wrote: > > > BTW, I thought again about the terminology of "list" versus "cons pairs" > and > plain "cells". "list" is a rather unprecise term, I feel it is not limited > to "a > chain of cells with NIL at the end". I use "list" for any sequence of > cells (as > opposed to other structures like "tree", "graph" or "set"). These include > also > e.g. "circular lists" like (1 2 3 .), which have no NIL at the end (in > fact, no > end at all). > Ok, so from this point of view every cons pair is a list even those with a dotted pair in the tail But I think it's interesting to distinguish between two different kind of lists, those having a NIL symbol in last cell CDR (let's say ending in NIL symbol) and with a non NIL in las cell CDR (those ending in a symbol not NIL) just because of almost every function dealing with lists assume they belong to NIL-ending kind. I mean, with a NIL ending list you have an empty list condition (NIL) but how do you know a non-NIL ending list is empty? and since most functions dealing with lists have a recursive pattern looking for an empty list condition to finish processing the list I think it would be interesting to discriminate between those two kinds of lists. For example, let's define f as: (de f (L) (print (car L)) (if (<> NIL (cdr L)) (f (cdr L then f is well defined for NIL ending lists but fails with non-NIL ending lists > > but when describing functions ' is a notation mark with a > > semantic, what is the semantic of dot notation mark when used in formal > > parameters in function description? > > > > I mean, you have these two notations for functions: > > > > - (dbs+ 'num . lst) > > > > - (delete 'any 'lst) -> lst > > > > are they applied the same? with the same kind of parameters? > > The functions behave differently. (dbs+ 'num . lst) means that the the > function > takes an unlimited number of arguments, where only the first one is > evaluated, > while (delete 'any 'lst) takes two evaluated arguments. what about these two? are they equivalent? (f num lst) -> num (g num . lst) -> num > > > evaluate to a number and rest of parameters will be bound to Z, so you > call > > this function like (dbs+ 4 a b c) , what notation will you use to > express > > you have to pass a list as parameter to a function? maybe (dbs+ 'lst) ? > I > > These function definitions say nothing about the types of the arguments > like > number, list etc. This is determined by the behavior of the function's > body. > > of course it's the function body which determines the "type" of parameters, if the body applies a parameter to a function expecting a number, that parameter's type must be a number and not a symbol or list or the function call in the body will fail, but you use a notation for describing functions just to help users know what kind of parameter you must provide, that's the reason to use that list of meaningful words, type is not enforced (not possible) but suggested to user using the function, right? so a function described as(f 'num 'num) informs that function f expects two parameters being numbers and since parameters are evaluated it's the value what is expected to be numers, so you can call f as (f 1 2) or (f a b) or even (f (x y z) 3) provided that values of symbols a and b are numbers and the result of x function call (x y z) returns a number but sure you cannot call f as (f (1 2)) or (f 'x 4) >From this point of view my question is about the difference of using or not using dot when describing a function, for example, take the if description: (if 'any1 any2 . prg) -> any Would the description below describe the same function? (if 'any1 any2 prg) -> any Even more, having into account notation used for describing functions I know: any - Anything: Any data type prg - Prog-Body: A list of executable expressions (run) so from description of function "if" which is "Conditional execution: If the condition any1 evaluates to non-NIL, any2 is evaluated and returned. Otherwise, prg is executed and the result returned." I undestand the "then" clause is any2 which gets evaluated when evaluated any1 is T and also it could be any type of value while prg is the "else" clause being evaluated only if evaluation of any1 returns NIL and also it is a list of executable expressions, from this I understand the following is a list of valid and invalid if function calls: (if T 3 (print "no")) # valid (if (< 2 2) 'x (print "yeah"))# valid (if T 3 4)# invalid because 4 is a number not a prg (a list) (if NIL (print "then") (print "else") (print "finally")) # a doubt here, I think it's invalid because two executable expressions are two lists not one prg (one list of executable expressions) prg - Prog-Body: A list of executable expressio
Re: a bunch of questions about syntax
On Thu, Jan 26, 2017 at 11:35:20PM +0100, pd wrote: > Alex, thanks a lot for your very clarifier reply (specially the procedural > way of thinking which makes a lot of sense to me), I'm still confusing in a > couple of things... No problem! BTW, I thought again about the terminology of "list" versus "cons pairs" and plain "cells". "list" is a rather unprecise term, I feel it is not limited to "a chain of cells with NIL at the end". I use "list" for any sequence of cells (as opposed to other structures like "tree", "graph" or "set"). These include also e.g. "circular lists" like (1 2 3 .), which have no NIL at the end (in fact, no end at all). > I've read in docs that the ' prefix in a name of formal parameter when > describing a funcion indicates it's a evaluated parameter (even when the Yes > opposite is clearer to me , using ' to indicate a non-evaluated parameter > following the quote notation you use when want to preserve something from > evaluation) That would also make sense. I think the notation in the docs mirrors *some* typical call scenarios. > but when describing functions ' is a notation mark with a > semantic, what is the semantic of dot notation mark when used in formal > parameters in function description? > > I mean, you have these two notations for functions: > > - (dbs+ 'num . lst) > > - (delete 'any 'lst) -> lst > > are they applied the same? with the same kind of parameters? The functions behave differently. (dbs+ 'num . lst) means that the the function takes an unlimited number of arguments, where only the first one is evaluated, while (delete 'any 'lst) takes two evaluated arguments. > So I suppose the notation (dbs+ 'num . lst) refers to a function defined as > (de dbs+ X . Z ...) and thus first parameter is binded to X and also must Yes, (de dbs+ (X . Z) ..) to be precise. > evaluate to a number and rest of parameters will be bound to Z, so you call > this function like (dbs+ 4 a b c) , what notation will you use to express > you have to pass a list as parameter to a function? maybe (dbs+ 'lst) ? I These function definitions say nothing about the types of the arguments like number, list etc. This is determined by the behavior of the function's body. To indicate that an argument is *expected* to be a list, I usually use 'Lst' (de foo (Lst) .. > mean a notation to express you *must* call a function using a list like (f > (a b c)) and not (f a b c) Note that (f (a b c)) does not mean that a list will be passed, but depends on the return value of the function 'a'). Same for (f a b c), it depends on the values of the symbols 'a', 'b', and 'c'. There is no strict, static notation for the types of arguments to a function. This is a dynamic issue. > Also taking about dot, as you said you have to use delimiters to separate > symbols and thus you must surround dot with spaces (or any other delimiter > I suppose, probably you can write the weird sentence (a,.,b) as an > alternative to (a . b) dotted pair), so I suppose dot is kind of operator > (maybe a read macro as ' ?) anyway I think it would be interesting if dot It is *similar* to a read macro, as it controls the behavior of the reader. I would not call it a "macro", because it has no corresponding expanded or evaluated representation, like: 'abc -> (quote . abc) `(* 3 4) -> 12 Instead, it is Lisp "syntax", on the same level as parentheses etc. > could act as an operator being associative to the right, so you can write: > > ( a . b . c . d . NIL) > > to be equal to > > (a . (b . (c . (d . NIL > > and also equal to (a b c d) > > does it have any sense? It would be possible to change the reader to accept (a . b . c . d . NIL), but I'm not sure at the moment. Would there be any advantage? ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: a bunch of questions about syntax
Alex, thanks a lot for your very clarifier reply (specially the procedural way of thinking which makes a lot of sense to me), I'm still confusing in a couple of things... I've read in docs that the ' prefix in a name of formal parameter when describing a funcion indicates it's a evaluated parameter (even when the opposite is clearer to me , using ' to indicate a non-evaluated parameter following the quote notation you use when want to preserve something from evaluation) but when describing functions ' is a notation mark with a semantic, what is the semantic of dot notation mark when used in formal parameters in function description? I mean, you have these two notations for functions: - (dbs+ 'num . lst) - (delete 'any 'lst) -> lst are they applied the same? with the same kind of parameters? I mean, if I describe the function F as being: - (F 'num lst) -> num am I saying the same as if I describe it this way?: - (F 'num . lst) -> num if not, what is the difference? > and what means the following notation? > > > > - (dbs . lst) > > This notation is meant to represent a function like > >(de dbs Lst ..) > > so that a call > >(dbs a b c d) > > binds (a b c d) to 'Lst'. > >(dbs a b c d) = (dbs . (a b c d)) > > So I suppose the notation (dbs+ 'num . lst) refers to a function defined as (de dbs+ X . Z ...) and thus first parameter is binded to X and also must evaluate to a number and rest of parameters will be bound to Z, so you call this function like (dbs+ 4 a b c) , what notation will you use to express you have to pass a list as parameter to a function? maybe (dbs+ 'lst) ? I mean a notation to express you *must* call a function using a list like (f (a b c)) and not (f a b c) Also taking about dot, as you said you have to use delimiters to separate symbols and thus you must surround dot with spaces (or any other delimiter I suppose, probably you can write the weird sentence (a,.,b) as an alternative to (a . b) dotted pair), so I suppose dot is kind of operator (maybe a read macro as ' ?) anyway I think it would be interesting if dot could act as an operator being associative to the right, so you can write: ( a . b . c . d . NIL) to be equal to (a . (b . (c . (d . NIL and also equal to (a b c d) does it have any sense?
Re: a bunch of questions about syntax
Hi Pd, >- three base data types: Numbers, Symbols and Cons Pairs (Lists), >... > suggesting dotted pairs are the same as lists, both are > indistinguishable so it should be possible to write any list as a dotted > pair, i. e. (1 2) = (1 . (2 . NIL)) but what is the list for (1 . 2) dotted > pair? Lists are a special kind of cons pairs. We call it a list if the last cell has NIL in its CDR, just like in your example. So both (1 2) and (1 . 2) are cons pairs. In fact, each cell in a list is a cons pair), but only (1) or (1 2) is called a list. > 2- In the same doc talking about function arguments you can read "A lambda > expression always has a list of executable expressions as its CDR. The CAR, > however, must be a either a list of symbols, or a single symbol ... > a) : (de foo (X Y . Z) # CAR is a list with a dotted-pair > tail Right > According with the parameters rules the first is supposed to bind X to the > first evaluated parameter, Y to the second and Z to the rest of parameters Yes > but here the rule to apply is the first one, car is a list of symbols (X, Y > and Z the last two in the dotted pair Y.Z) so every symbol must be binded > to evaluated parameters No, the 'Z' means that the rest of the symbols is *not* evaluated. > (foo (1 2 3 4)) > > should bind 1 to X, 2 to Y and 3 to Z discarding 4 but the examples says it > really binds 1 to X, 2 to Y and (3 4) to Z thus effectively merging first No. It binds X to (1 2 3 4), and both Y and Z to NIL If you call (foo 1 2 3 4) then it binds X to 1, Y to 2 and Z to (3 4). > b) : (de foo (X . @) # CAR is a dotted-pair with '@' > > This case is similar to the previous but merging first and second rules but > in this case first rule doesn't apply because as comment remarks CAR is a > dotted pair not a list Perhaps it helps to think about this procedurally: While the list of formal parameters is a cons pair (i.e. not atomic), the next symbol is popped of and the evaluated parameter bound to it. Then, if the remaining piece is not NIL, the rest of the list is bound to it unevaluated. So if the "list" of formal parameters is just Z (de foo Z ..) (foo 1 2 3 4 5) then 'Z' is bound to (1 2 3 4 5). On the other hand, if it is (X Y . Z) (de foo (X Y . Z) (foo 1 2 3 4 5) then first X is popped off : (setq Lst '(X Y . Z)) -> (X Y . Z) : (pop 'Lst) -> X so 'X' is bound to 1. 'Lst' is now : Lst -> (Y . Z) again, we pop : (pop 'Lst) -> Y so we bind Y to 2. But now 'Lst' is : Lst -> Z It became atomic! So we are back at the "simple" case above where we had (de foo Z ..) and Z is bound to (3 4 5). The same systematics apply to cases like (de foo @ ...) and (de foo (X Y Z . @) Does this make sense? > and what means the following notation? > > - (dbs . lst) This notation is meant to represent a function like (de dbs Lst ..) so that a call (dbs a b c d) binds (a b c d) to 'Lst'. (dbs a b c d) = (dbs . (a b c d)) > 4- Usually in classical lisp syntax you must use dot surrounded by spaces > to indicate a dotted pair, I supposed this will be the same in picolisp > because of fixed point numbers notation so you always shoud use (sym . sym) Yes. The dot is not a delimiter. Atoms are delimited by these characters: " \t\n\r\\"'(),[]`~{}" > to write a dotted paid in particular with transient symbols ("hello" . > "world") but I saw in this lists messages seeming to use the notation I would not write it this way, but always as ("hello" . "world"). However, ("hello"."world") is correctly read because the double qoutes are delimiters. Same with e.g. ("hello"("world")"!") I hope I could clear up some smoke. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe