Re: Let and Glue
Rick Hanson cryptor...@gmail.com writes: Hi Rick, Here is a problem (again!) with using a pil backquote expression, where the user, like you or me, is stuck on CL-unquote thinking. Let's call g again, but now we switch the places of the dates and times. In this case, we might expect the answer now to be No; however, the answer will remain Yes. : (g Is $S1$ before $S2$? The answer is `(if (and (= $D2$ $D1$) (= $T2$ $T1$) ) Yes No ) ) - Is \1999-09-09 20:12:05\ before \2000-03-04 18:03:03\? The answer is \Yes\ Why? Because when the backquote expression gets resolved by the reader, the symbols $D1$, $D2$, $T1$, and $T2$ are not bound to any values (i.e. will evaluate to NIL). And since (= NIL NIL) evals to T, g will always see Yes as its last argument. Sorry. That means you have to come up with another way to eval code in your DSL (i.e the stuff under g). I hope this make sense. This is what Alex has been trying to tell us all along. (I only now just realized this; so you can see how far I've come along: not much.) thanks for your improvements of my rather crude function and for the final hint that using (date) in the examples was a rather bad idea since (date) works with NIL args too, it just gives different results. This backquote/comma mechanism in Emacs Lisp seemed so natural to me I never really thought about the way it works. So I should rather think about function calls then read syntax. But maybe not in public, I don't want to drive more people off the mailing list ;-) However, I will use your factorized code as starting point for new investigations, thanks again! -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Alexander Burger a...@software-lab.de writes: Hi Alex, sorry for being thick as a brick ... Well, 'bind' is the evaluating version of 'let'. It could be used to implement the outher functions. I'll check that out. What you probably mean is something different. It is a different way of interpreting the arguments to a function. It has nothing to do with how the symbols are bound, and nothing with the reader: (de g Args (glue (mapcar '((X) (if (pair X) (val (car X)) X) ) Args ) ) ) (setq Temp 33) (g Current \temperature\ in Berlin is (Temp) °Celsius \(its really hot!\) ) - Current \temperature\ in Berlin is 33 °Celsius (its really hot!) This comes pretty close to what I was looking for, thanks. The only drawback is that normal parens (and double quotes) are very common in text so a lot of escaping would be necessary. Something like this: (g Current temperature in Berlin is {Temp} \{°Celsius\} (its really hot!) ) resulting in: - Current \temperature\ in Berlin is 33 {°Celsius} (its really hot!) would be much more comfortable as syntax, but harder to implement. -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Hi Rick + Thorsten, On Sat, Aug 08, 2015 at 11:43:03PM +0200, Thorsten Jolitz wrote: Rick Hanson cryptor...@gmail.com writes: Yeah, sorry. I had this on the mind -- a different animal altogether. $ sbcl * (let ((X (+ 3 4))) `(hello ,X ,(- X 9))) (HELLO 7 -2) Maybe I was confused by Emacs Lisp a bit too: , | (let ((x (+ 3 4)) | (y (+ 5 6))) | `(+ 5 x ,y)) | | - (+ 5 x 11) ` Yes, this is confusing. In CL and Emacs the backquote is actually a *function*, in the same way as 'quote' is a function in PicoLisp. In all systems, the quote character (') is a read-macro: PicoLisp '(a b c) = (quote a b c) Other '(a b c) = (quote (a b c)) In PicoLisp, the backquote is *not* a function. It is immediately replaced by the reader with the result of the evaluation. In other Lisps, the backquote is probably also a read-macro, similar to 'quote', in that it returns a function call to be evaluated later at runtime. It could be something like `(a b ,c d) = (backquote a b , c d) In PicoLisp, the function closest to backquote (though a litte different) is 'fill'. , | A single backquote character ` will cause the reader to evaluate | the following expression, and return the result. | | : '(a `(+ 1 2 3) z) | - (a 6 z) | | A tilde character ~ inside a list will cause the reader to evaluate | the following expression, and (destructively) splice the result into | the list. | | : '(a b c ~(list 'd 'e 'f) g h i) | - (a b c d e f g h i) ` it looks to me as if the difference between PicoLisp and others (like Emacs Lisp) must be rather in the 'let than in the read macros, since No! Nothing to do with 'let'. the combination quote/backquote in PicoLisp is equivalent to the combination backquote/comma in other Lisps, and works the same, except inside let bindings: Nonono! The backquote in PicoLisp has NOTHING at all to do with the 'quote' function. It is a completely separate thing. 'quote' is just a normal function, which at *runtime* returns its arguments un-evaluated. It makes perfect sense to have backquote without 'quote' : (de foo (X) (* X `(+ 3 4)) ) : (pp 'foo) (de foo (X) (* X 7) ) It seems still not to be clear that the important point is WHEN an expression is evaluated. Please try to understand what READ/EVAL really means. It is the same in all Lisps in that regard. PicoLisp: , | $ pil + | : (let X (+ 2 3) '(3 4 `X)) | - (3 4 NIL) Yes. The expression (let X (+ 2 3) '(3 4 `X)) only makes sense if 'X' was defined before it is READ. e.g. $ pil + : (setq X 7) ... : (let X (+ 2 3) '(3 4 `X)) - (3 4 7) vs Emacs Lisp: , | (let ((X (+ 2 3))) `(3 4 ,X)) | - (3 4 5) | | `(3 4 ,(+ 2 3)) | - (3 4 5) ` How would the above behavior inside let bindings be achieved in PicoLisp? Either : (let X (+ 2 3) (list 3 4 X)) # I would prefer a simple 'list' - (3 4 5) or : (let X (+ 2 3) (fill (3 4 X) 'X)) # Rick tried 'fill' too - (3 4 5) or : (let @X (+ 2 3) (fill (3 4 @X))) - (3 4 5) or whatever function you like to build the list. Note that also in CL and Emacs the backquote function builds a list at *runtime*, just like 'list' or 'fill' do. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Thorsten Jolitz tjol...@gmail.com writes: Hi Alex, When I quote the reference: , | A single backquote character ` will cause the reader to evaluate | the following expression, and return the result. | | : '(a `(+ 1 2 3) z) | - (a 6 z) ` it looks to me as if the difference between PicoLisp and others (like Emacs Lisp) must be rather in the 'let than in the read macros, since the combination quote/backquote in PicoLisp is equivalent to the combination backquote/comma in other Lisps, and works the same, except inside let bindings: PicoLisp: , | $ pil + | : (let X (+ 2 3) '(3 4 `X)) | - (3 4 NIL) | : '(3 4 `(+ 2 3)) | - (3 4 5) ` vs Emacs Lisp: , | (let ((X (+ 2 3))) `(3 4 ,X)) | - (3 4 5) | | `(3 4 ,(+ 2 3)) | - (3 4 5) ` How would the above behavior inside let bindings be achieved in PicoLisp? Thinking about it it seems that Read Macros are equivalent, but the readers work differently: - PicoLisp :: read without eval, except when encountering a read macro - Emacs Lisp :: read without eval, except in special situations (local assignments, read macros, ???) So assignments inside 'let are treated special too, like implicit read macros, and evaluated during reading. Not only that I have a concrete use case for that behavior right now (wrt to let and job), I find that very useful in general. The only advantage of the current PicoLisp behavior I can see is speed of reading (because of less assignments in the process), but there might be others of course. Would it be conveivable to have 'evaluating versions' of some of the binding environments in PicoLisp too? , | let, let?, bind, recur, with, for, job, use ... ` Here a possible use case: Imagine these two functions are given: , | (de g Txt |(glue Txt) ) | | (de getCurrTemp (Url) # should retrieve temperature from url | 33 ) ` than even a non-programmer could specify a dynamic report in PicoLisp by writing: , | (job | CurrTemp (getCurrTemp /path/to/current/temp/in/berlin) | | (g Current temperature in Berlin is `CurrTemp °Celsius) ) ` i.e. by using PicoLisp as a kind of smart/dynamic markup language instead of defining and calling functions like a programmer. Of course this could easily be done by 'normal' programming, but I'm looking for something like the above ... -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Alexander Burger a...@software-lab.de writes: Hi Alex, uhh ... bad timing from my side, writing more confused question while you are actually answering them at the same time... Either : (let X (+ 2 3) (list 3 4 X)) # I would prefer a simple 'list' - (3 4 5) or : (let X (+ 2 3) (fill (3 4 X) 'X)) # Rick tried 'fill' too - (3 4 5) or : (let @X (+ 2 3) (fill (3 4 @X))) - (3 4 5) or whatever function you like to build the list. Note that also in CL and Emacs the backquote function builds a list at *runtime*, just like 'list' or 'fill' do. I have to try fill, and think more about the whole issue, but the last version with @X looks pretty close to what I'm looking for. Again, thanks for the explanations (and patience)! -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Hi Thorsten, I have to try fill, and think more about the whole issue, but the last version with @X looks pretty close to what I'm looking for. Ah, yes, didn't think about that when I wrote the last mail. This is also a possibility: (de g Lst (fill Lst) ) (setq @Temp 33) (g Current temperature in Berlin is @Temp °Celsius) - (Current temperature in Berlin is 33 °Celsius) ♪♫ Alex On Sun, Aug 09, 2015 at 10:50:11AM +0200, Alexander Burger wrote: (de g Args (mapcar '((X) (if (pair X) (val (car X)) X) ) Args ) ) (setq Temp 33) (g Current temperature in Berlin is (Temp) °Celsius) - (Current temperature in Berlin is 33 °Celsius) -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Thorsten Jolitz tjol...@gmail.com writes: Hi List, This comes pretty close to what I was looking for, thanks. The only drawback is that normal parens (and double quotes) are very common in text so a lot of escaping would be necessary. Something like this: (g Current temperature in Berlin is {Temp} \{°Celsius\} (its really hot!) ) resulting in: - Current \temperature\ in Berlin is 33 {°Celsius} (its really hot!) would be much more comfortable as syntax, but harder to implement. I implemented something close to my goal, with $xyz$ syntax for arguments to be evaluated: , | (de f Args | (mapcar | '((Arg) |(if (atom Arg) | (let (ChopArgs (chop Arg) | ArgsTail (tail 2 ChopArgs) | PunctChars (chop .,;:?!\'_-{[]} ) | ArgLst NIL | Punct NIL ) | (ifn (and | (= (car ChopArgs) $) | (or |(= (last ChopArgs) $) |(and | (= (car ArgsTail) $) | (member (last ArgsTail) PunctChars) | (setq Punct (last ArgsTail)) | (setq ChopArgs (head -1 ChopArgs) | ) ) ) ) | Arg | (pack |(val | (intern | (pack | (tail -1 (head -1 ChopArgs)) ) ) ) |Punct ) ) ) | (f Arg) ) ) # use recur/recurse instead? | Args ) ) ` using it returns an almost perfect list result: , | (setq |D1 (date 1999 09 09) |D2 (date 2000 03 04) |T1 (time 20 12 05) |T2 (time 18 03 03) |S1 (stamp D1 T1) |S2 (stamp D2 T2) ) | | (f Is $S1$ before $S2$? |The answer is |`(if (and |(= $D1$ $D2$) |(= $T1$ $T2$) ) |Yes |No ) ) | | | - (Is 1999-09-09 20:12:05 before 2000-03-04 18:03:03? The answer is Yes) ` only that 2000-03-04 18:03:03? should rather be 2000-03-04 18:03:03? I did not yet make it to write a function g in the spirit of: , | (de g Args | (glue (f Args)) ) # does not work ` that then returns a single string: , | Is \1999-09-09 20:12:05\ before \2000-03-04 18:03:03\? The answer is \Yes\ ` -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Please unsubscribe me. I really just wanted to follow progress on the Picolisp cpu. If you have a pciolisp cpu announce list, then please add me to it. Chris -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Hi Christopher, On Mon, Aug 10, 2015 at 07:17:12AM +0200, Christopher Lozinski wrote: Please unsubscribe me. Please send a message with the subject Unsubscribe to the list. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Hmm, read-macros seem indeed a lot misunderstood. NEVER use a read-macro to insert values which are defined at *run*time! As the name says, they are evaulated at *read* time! Maybe I too have been misunderstanding all along. Alex, you seem to be inferring here a strict separation between readtime and runtime; however, I see eval process as intertwining them. So, are you saying that the following is a kind of abuse (since I am insert[ing] values which are defined at *run*time with a *read* macro) and that it gives me the answer I'm looking for is some kind of happy coincidence (despite my misunderstanding of the eval model)? :) ? (let X (+ 3 4) (glue '(Number `X `(- 4 9 - Number 7 -5 Or this, even? ? (let X (+ 3 4) (glue '(Number `X `(- X 9 - Number 7 -2 It seems to me that *read*ing is inherently involved in *run*time (the eval process, which is recursive of course). For instance, X in the above expressions is at some point, in the eval process, bound to 7 before the expression '(Number `X `(- X 9)) is evaluated, and that the evaluation of this expression goes through a reckoning of read macros first (under the context of the current runtime environment which has X bound to 7). If so, aren't then the `let` expression usages above *not* problematic? Or am I thinking about this incorrectly? Thanks! -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Oops. I got that all wrong. Look. $ pil : X - NIL : (let X (+ 3 4) (glue '(Number `X `(- X 9 - Number : X - NIL When I copied and pasted results in my last message, I was in a pil session where I was messing around with `fill` and `run` and it polluted what I thought was my top-level. Here was the culprit. : (let X (+ 3 4) (run (fill '(glue (Number X `(- 4 9))) '(X !? (Number 7 -5) Number -- Undefined ? X - 7 But I didn't notice all along that I was at the question mark prompt and thus *not* at the top-level. Oops. So I don't understand. Back to the drawing board. :) Sorry for the noise. -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Alexander Burger a...@software-lab.de writes: Hi Alex, I wonder how I can use local variable X inside of the 'glue' argument list: , | : (let X (+ 3 4) X) | - 7 | | : (let X (+ 3 4) (glue '(Number X `(- 4 9 | - Number X -5 | | : (let X (+ 3 4) (glue '(Number `X `(- 4 9 | - Number -5 ` X does not seem defined in the last expression although its surrounded by (let X (+ 3 4) ...). Hmm, read-macros seem indeed a lot misunderstood. NEVER use a read-macro to insert values which are defined at *run*time! As the name says, they are evaulated at *read* time! You could do this: : (let X (+ 3 4) (glue (list Number X `(- 4 9 (the second read-macro is OK, as the (- 4 9) may be evaluated at read-time) Ah, I see, thanks. I think the (working) second read-macro fooled me a bit, and I did not have separation of read- and runtime very clear. Well, nice that, as always with PicoLisp, there is an easy way to make it work ;-) -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Hi Rick, you clarified your (incorrectly correct) results in your next mail, so let me explain more about read- and runtime. Maybe I too have been misunderstanding all along. Alex, you seem to be inferring here a strict separation between readtime and runtime; Yes, indeed. It seems to me that *read*ing is inherently involved in *run*time (the eval process, which is recursive of course). You must strictly separate READ from EVAL (if we ignore read-macros for the moment). Lisp is a REPL, a Read/Eval/Print-Loop. The Print only happens on the top level, so what we actually have is a loop which READs expressions and EVALuates them. While reading, no evaluation takes place. It is just a conversion of human-readable text to internal cell structures. Now read-macros extend this, or mix it up. When, while reading and expression character by character, the interpreter sees a backquote or a tilde, it 'read's the following expression recursively, calls EVAL on it, and uses the result instead of what it did read. In most programs, you don't have just two times (read and run). Sometimes there are many levels involved. Consider this: (setq CONST 7) (de foo (Lst) (mapcar '((X) (bar (mumble (+ X `(* 2 CONST) Lst ) ) First (setq CONST 7) is read, and evaluated, calling the function 'setq'. As a side-effect, the symbol CONST is set to 7. Then the second expression is read. This causes the read-macro (* 2 CONST) to be evaluated, so the reader returns this list: (de foo (Lst) (mapcar '((X) (bar (mumble (+ X 14 Lst)) This list is evaluated, causing the function 'de' to run. As a side-effect, the value of 'foo' is set to the list ((Lst) (mapcar '((X) (bar (mumble (+ X 14 Lst)) Then, at some LATER time, somebody calls 'foo'. We might call it the third level. It causes the function 'mapcar' to be called, which receives as its first argument the list ((X) (bar (mumble (+ X 14 Then, again a little later, 'mapcar' calls this list as a function. Even more levels we have in this GUI fragment: (action (html 0 Test lib.css NIL (h3 NIL Test) (form NIL (gui '(+Button) Dialog '(dialog NIL (gui 'txt '(+Init +TextField) (val (: top 1 txt)) 12) (okButton '(msg (val (: home txt (gui '(+Button) Alert '(alert NIL Bla bla bla () (okButton) ) ) (cancelButton) ) ) ) ) ) 1. When the browser arrives at this page, this file is 'loaded'. 'load' reads and evaluates all expressions in the file. So the list (action ...) is read. 2. The list is evaluated: Calling (action (html ...)) builds a form data structure, and sends HTML code back to the browser. In that course the 'gui' function is called and builds a button component labeled Dialog. The list (dialog NIL ...) is stored in the button, but not yet evaluated. 3. If the user clicks on the button labeled Dialog, the 'dialog' function runs. It builds a dialog data structure, and sends more HTML code back to the browser. Again the 'gui' function runs, and builds another button Alert in the dialog. The list (alert NIL Bla bla bla ..) is stored in THAT button, but not yet evaluated. 4. If the user clicks on THAT button, labeled Alert, then that list is evaluated, and an alert pops up. So you see, we have many different times of execution in a single expression. This can go on ad infinitum. ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Yeah, sorry. I had this on the mind -- a different animal altogether. $ sbcl * (let ((X (+ 3 4))) `(hello ,X ,(- X 9))) (HELLO 7 -2) Thanks, Alex, for taking the time and writing a very nice explanation. I believe I understand it, but I will re-read and ponder it more. -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Reading your other post I was wondering how it worked for you and thought it must be because of debug mode, and well ... correctly guessed ;-) Hi Thorsten! Yes. :) And btw thanks for picolisp-mode. Please count me as a happy user. -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Rick Hanson cryptor...@gmail.com writes: Yeah, sorry. I had this on the mind -- a different animal altogether. $ sbcl * (let ((X (+ 3 4))) `(hello ,X ,(- X 9))) (HELLO 7 -2) Maybe I was confused by Emacs Lisp a bit too: , | (let ((x (+ 3 4)) | (y (+ 5 6))) | `(+ 5 x ,y)) | | - (+ 5 x 11) ` Thanks, Alex, for taking the time and writing a very nice explanation. I believe I understand it, but I will re-read and ponder it more. 1+ Many thanks for that in detail explanation, its actually a bit confusing especially when one is used to other Lisps too. When I quote the reference: , | A single backquote character ` will cause the reader to evaluate | the following expression, and return the result. | | : '(a `(+ 1 2 3) z) | - (a 6 z) | | A tilde character ~ inside a list will cause the reader to evaluate | the following expression, and (destructively) splice the result into | the list. | | : '(a b c ~(list 'd 'e 'f) g h i) | - (a b c d e f g h i) ` it looks to me as if the difference between PicoLisp and others (like Emacs Lisp) must be rather in the 'let than in the read macros, since the combination quote/backquote in PicoLisp is equivalent to the combination backquote/comma in other Lisps, and works the same, except inside let bindings: PicoLisp: , | $ pil + | : (let X (+ 2 3) '(3 4 `X)) | - (3 4 NIL) | : '(3 4 `(+ 2 3)) | - (3 4 5) ` vs Emacs Lisp: , | (let ((X (+ 2 3))) `(3 4 ,X)) | - (3 4 5) | | `(3 4 ,(+ 2 3)) | - (3 4 5) ` How would the above behavior inside let bindings be achieved in PicoLisp? -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: Let and Glue
Rick Hanson cryptor...@gmail.com writes: Hi Rick, Reading your other post I was wondering how it worked for you and thought it must be because of debug mode, and well ... correctly guessed ;-) Hi Thorsten! Yes. :) And btw thanks for picolisp-mode. Please count me as a happy user. Oh, you have to thanks Guillermo R. Palavecino in the first place, since he wrote it: , | ;; picolisp-mode: Major mode to edit picoLisp. | ;; Version: 1.3 | | ;;; Copyright (c) 2009, Guillermo R. Palavecino | ;;; Copyright (c) 2011, 2012 Thorsten Jolitz ` I just became the (rather inactive) maintainer a few years ago and did some enhancements later on, expecially to inferior-picolisp.el. -- cheers, Thorsten -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe