freenode/#lisp - IRC Chatlog
Search
7:10:57
beach
scymtym: For Second Climacs, I want the reader to return parse-results, or as I call them in Second Climacs "wad"s. A wad is a nested data structure that contains source positions corresponding to the start and the end of the thing that was read, and also a list of children, which are also wads. And the children are represented as a list of wads in the order that they were read.
7:13:29
beach
2. Add the possibility for Eclector to return wads, just the way it can now return CSTs.
7:14:13
beach
The thing is complicated by the fact that in Second Climacs I ultimately want CSTs as well.
7:15:03
beach
So then, for solution 1 I can convert wads to CSTs. Just drop the non-expressions and apply a similar technique that Eclector itself uses to construct a CST from a bunch of children.
7:16:33
beach
2.2 Use solution 2, and factor the code so that there is no duplication, i.e. build the CSTs from the wads.
7:19:07
beach
The thing is complicated by the fact that, for Second Climacs, I want to make the parser incremental. I guess I need to think about the interaction between the cache manager and the reader. It is entirely possible that it can not be turned incremental with solution 2.
7:20:30
phoe
beach: for an incomplete expression, is it possible that you return a "special" wad at the end of each list of children that is used as a mark that this expression is incomplete?
7:21:10
phoe
I imagine that for an incomplete expression "(1 2 3" it could be a list resembling (#<WAD 1> #<WAD 2> #<WAD 3> #<EOF-WAD>) or something similar.
7:21:34
phoe
If a list contains an EOF-WAD, then the expression is incomplete, but you can nonetheless return the parse result.
7:22:02
phoe
And if you can return a parse result, then you should be able to make your parser incremental nonetheless.
7:25:39
beach
The reason I am asking all this is that such a wad reader could be useful in situations other than Second Climacs, and if so, it ought to be in a separate system.
7:45:36
beach
I see. Well, PARSE-RESULT turned out to be too long, so I had to choose something shorter.
10:56:26
scymtym
beach: i will have to think about this more, but i have an initial impression. i mentioned before that i would like to turn the eclector-concrete-syntax-tree code into two parts: 1) a protocol for constructing parse results 2) a client of that protocol that constructs CSTs. my impression is that such a protocol (modulo omissions that become apparent when it is used) would be sufficient for the three clients i am aware of: 1) the CST
15:10:38
Ukari
is there any consensus or principle about function api design? There are two ways and which is better ? multiple returned values, or (list (cons :key1 xx) (cons :key2 xx) (cons: key3 xx))
15:11:24
White_Flame
now, if those keys are optional, then you might want to return that and descructure
15:22:37
jackdaniel
if function returns multiple values use multiple values, that way you don't cons unnecessarily
15:26:53
Bike
this isn't even more efficient, you cons up three closures, whereas you only need zero closures
15:27:55
jackdaniel
well, in your situation (if you really need these lambdas inside), just do (defun hash () (let (storage) (values #'(…) #'(…) #'(…))))
15:28:23
Xof
I am having difficulty building an implementation of case using a jump table without consing at runtime (and, worse, doing O(n) initialization at runtime). I wonder if I'm missing something or if that is indeed the best I can do
15:29:05
Ukari
in values #'(...)... way, if i want to call :set or :get, the code need to provide a exact position
15:29:59
jackdaniel
Ukari: whenever you remember that first is init, second is set and third is get, or that you remember that there is assoc :init, assoc :set and assoc :get still makes you remember *things* as a programmer
15:31:09
Ukari
jackdaniel, but if i need to add another :setFoo, i must add it to the last position or it will mess up the code before
15:31:50
jackdaniel
Ukari: for me thsi programming style is unreadable anyway, when I want functions I define them with names and provide argument to them
15:31:59
Bike
i mean, an "actual" jump table is like having a GO special operator that evaluates its argument
15:32:24
Xof
the good news is that means I can forget about my case-using-perfect-hashes, at least for now, and move on to find-restart-using-perfect-hashes
15:33:00
jackdaniel
Ukari: eventually (if I really must) I can always define dynamic variable and create dynamic context for these functiosn with let, that way I have only one thing to carry in the application instead of n functions
15:33:48
jackdaniel
Ukari: I admit that these advices are very opinionated, but you have asked about opinions ;)
15:34:54
Ukari
show me the example about `define dynamic variable and create dynamic context for these functiosn with let`, it sounds interesting
15:37:09
jackdaniel
(defvar *foo*) (defun init () (setf *foo* (make-hash-table))) (defun ukari-get () (gethash …)) (ukari-set () (setf (gethash …)))
15:37:53
jackdaniel
in body of this let form *foo* is bound to nil, outside this let form *foo* is not bound at all
15:43:33
jackdaniel
we could go on with improving your hack, but readable solution is to have argument to your set/get functions
15:44:05
pjb
Ukari: I would distinguish inner-loop functions from public API functions. The later, notably if they're intended to be invoked from the REPL, as commands, can have all kinds of sophisticated argument parsing, including &key and others (eg. catching additionnal arguments or list of arguments after the last &key, which is not parsed by default). But for internal functions, it may be better to use more plain lambda-lists, with only
15:44:25
jackdaniel
having dynamic context, or even worse – floating anonymous functions, makes your program hard to analyze
15:44:40
pjb
Ukari: and for results, multiple-values are probably the fastest way to return multiple values, even if you put a lot of NILs there for optional results.
16:47:56
Ukari
(iterate (for i in '(1 2 3 4)) (print i)), why this code tells 'The variable I is unbound'
17:08:58
foojin
jackdaniel: In your answer to Ukari, what did you mean by "floating anonymous functions"?
17:11:14
jackdaniel
each of them was not named, and I assume he would want to store them *somewhere*
17:12:43
Ukari
nameless lambda don't make global name confit but defun does, or it needs package name provided
17:12:44
foojin
jackdaniel: Ah, so it's just about passing them around so that it becomes difficult to know where did they come from.
17:13:45
phoe
Ukari: do you really need to generate code for each single hash element that you have?
17:13:56
jackdaniel
Ukari: I suspect you are a beginning CL programmer. I may be wrong, but if it is a case, you may learn a lot by following simple advices
17:14:13
phoe
and each single hash value is going to have a completely separate function that is going to be called?
17:15:08
jackdaniel
it is easier to maintain N variables with your "instances" and use directly gethash/setf gethash, then to maintain 3xN functions doing that for you
17:15:30
jackdaniel
if you have more complicated behavior, you maintain objects in variables and you specilize generic functions on their classes
17:15:45
Ukari
maybe i could store nameless lambda in a static way and pass varibale into it, like (let ((set (lambda (store) (lambda () ...)))) (defun hash () (list (cons :set (funcall set store)))))
17:15:48
jackdaniel
etc, that is something what people do, because it works and it provides easy structure of your program to follow
17:16:24
jackdaniel
but I think you are not interested in following this "nonsense", so I'm getting back to my Saturday ;-) see you \o
17:17:43
phoe
Ukari: grab a CLOS tutorial, read it and use it. You're going in a direction that is rarely used (because better mechanisms exist) and insanely hard to debug.
17:27:57
Ukari
i find a not-independent generator in this code, (iterate (for el in '(1 2 3 4)) (generate i from 1) (print (next i))). is there any standrad about independent generator?
17:30:21
phoe
Ukari: I think the only piece of manual for ITERATE is https://common-lisp.net/project/iterate/doc/index.html
17:41:15
Fare
Ukari: if you're heavy into functional style and going below the object system, Scheme might be more for you than CL.
17:52:17
fourier
not exacly lisp question but rather slime/sly, but how to get the last value returned in repl? like (sly-inspect "*") always inspects nil
18:01:38
fourier
what I want is to call sly's graphical inspector on *. but it always inspects nil :(
18:10:00
rme
Fare: The funding situation is not good. I have done a little paying work for about 1.5 clients.