libera/commonlisp - IRC Chatlog
Search
0:41:43
dbotton
Does IN-PACKAGE work with in an EVAL? in a PROGN? I get strange results one time no, one time yes
0:44:56
White_Flame
what do you mean by "work"? affect *package* for the calling environment, or for peer forms within PROGN?
0:48:26
White_Flame
the literal symol whose symbol-name is "SOMETHING" in that expression; that's an extant symbol in a sexpr list that is xyz:something, or that is a string on the REPL that is being read?
0:50:26
White_Flame
ok, so while (something) is executing, *PACKAGE* should be XYZ, as well as when it returns
0:50:45
EdLangley[m]
IN-PACKAGE would affect package, but by the time you call EVAL, it's too late to adjust the package read symbols belong to
0:50:59
White_Flame
right, if it's a constructed sexpr, though, I don't think the reader is involved
0:51:29
White_Flame
hence asking if the symbol xyz:something is already constructed before that EVAL form is reached
0:52:33
White_Flame
so, when you read "(eval '(progn (in-package ....)...))", the value of *PACKAGE* will be used to construct the symbols well before EVAL or the inner IN-PACKAGE is evaluated
0:53:25
White_Flame
so when running a file, the reader needs to be called per toplevel form and then executedevaluated before the next toplevel form is read
0:54:47
Alfr
EdLangley[m], in-package sets cl:*package*, and the compiler has to treat top-level in-package specially to have the same effect, that's about it.
0:56:15
White_Flame
EdLangley[m]: yes, lisp source code forms are mutators against the running image
0:58:13
White_Flame
no, macro use of functions are compile-time, not load time. so eval-when boosts it earlier
1:00:04
Bike
if (setf package (find-package :foo)) is a toplevel form with no eval-when etcs around it, it will run at load time
1:00:17
Bike
you can kind of think as :load-toplevel :execute as being the default state before any eval-whens come in
1:00:48
White_Flame
dbotton: heh. Well, when you _read_ the string in to a list, that's where the packages are assigned to the symbols
1:01:17
White_Flame
and that happens before eval. So you need to (let ((*package* (find-package :xyz))) (read-from-string "(progn ...)"))
1:02:45
White_Flame
so yeah, if you have a variety of packages you might want to read inside of, then that'll generally have to be sideband information outside the string
1:03:05
White_Flame
"(progn #.(in-package :xyz) ...)" is also a terrible hack that will work, but also leave the caller's package changed
1:04:06
White_Flame
specifically, that it's around the read-from-string (or whatever READ-based thing) that makes it work
1:04:54
White_Flame
yep, just like toplevel .lisp (in-package ..), the compiler has to stop and swap packages before continuing the next read
1:06:01
Alfr
dbotton, you could use read and consume what you get form by form and check for an in-package form.
1:07:34
Alfr
dbotton, if you have a string, you may want to use with-input-from-string, so that READ will like it.
1:11:18
dbotton
EdLangley[m] take a look at - https://github.com/rabbibotton/clog/blob/main/demos/03-demo.lisp
1:13:29
White_Flame
(loop for line = (read-from-string ...) while line eval line) would support things like (in-package) moreso than "(progn ~a)"
1:19:25
White_Flame
once you have teh symbol CL:PROGN... yeah, all the other symbols are already read, too
1:20:37
EdLangley[m]
to pre-process the source code with its reader and turn all the symbols into PACKAGE::FOO
1:21:20
EdLangley[m]
I've done stuff like this occasionally when I want to print the code in a way that makes symbol packages unambiguous
1:22:04
EdLangley[m]
Yeah, because the first eval changes the package and then the second one evaluates in the right package
1:23:45
dbotton
that should not affected code already running correct? (ie it has already been read)
1:25:58
EdLangley[m]
I was doing this when I was serializing the code to a db and wanted it to be as unambiguous as possible
1:26:04
White_Flame
if there is #. or #= it won't round-trip and might mess with the timing & identity of objects
1:27:23
EdLangley[m]
:use :cl has the downside of making the code a bit ambiguous, because you have to assume it's always going to be read in a package that doesn't shadow symbols from :CL
2:17:35
EdLangley[m]
If I ever really return to this, I'm going to try to figure out how to use eclector to make a reversible reader
2:20:59
EdLangley[m]
I've sort of prototyped this for #+ and #-: https://github.com/fiddlerwoaroof/lisp-sandbox/blob/master/eclector-test.lisp
2:24:25
White_Flame
a reversible reader, assuming things don't mutate in the meantime, and just store the original string it read and print that as its representation :-P
2:27:46
White_Flame
just to be specific/pedantic, the brunt of the work goes in the printer, not necessarily extending the existing reader
2:40:00
EdLangley[m]
The idea would just be to have a s-expression format that doesn't lose things like #+feature or #.(...)
2:40:59
Alfr
White_Flame, just snapshot the universe for rollback and don't forget to destroy the one you abandon.
3:45:35
moon-child
drmeister, Bike: are you using llvm's built-in support for gc in clasp? If so, how have you found it?
4:12:52
mzan
Hi, I'm learning CL. Up so far this is the most complex code I wrote https://aoc-benchmarks.dokmelody.org/linux/program.php?test=aoc2021_day03b&lang=lisp&id=3
4:14:10
mzan
I like the (iter ...) macro a lot. But the (iter ...) macro initialize some variables to "nil" sometime, and the SBCL compiler refuse to apply some type optimizations because it sees an initial nil value and sometime it is not smart enough to figure out that the "nil" value will never be used.
4:16:22
mzan
My impression is that the majority of macros works well together but sometime there is some leak. It is acceptable, but it is rather frustrating if one coded in more rigid languages like Haskell.
4:17:48
mzan
In this case specific, the leak was only related to optimizations, but not real semantic. Probably there are no many leaks on the side of the semantic.
4:19:13
moon-child
mzan: in such 'rigid' languages, you would probably not be allowed to write such code in the first place
4:21:02
moon-child
re iter/optimization: there was some loop/iter-like macro that purported to generate good code for pipelines of transformations. I can not now remember what it's called, but someone else may...
4:21:03
beach
mzan: There are several irritating style problems with your code, like mysterious blank lines, wrong number of semicolons in comments, incorrect indentation.
4:26:36
mzan
sm2n: I read something about type declarations in "iterate", but I will study it better. Thanks!
4:27:34
mzan
BTW, in case of doubts I can expand the code generated by the "iterate" macro, so for sure the problem was not obfuscated by the environment.
4:28:45
mzan
Probably in future I will try to micro-optimize the code, removing left notes signaled by SBCL, and benchmark the difference.
4:30:36
mzan
moon-child: I tried SERIES. In theory they should be superior to "iterate", because you can reuse chunks of code transforming data in different places. SERIES support this.
4:31:20
mzan
In practice, up to date, rarely I feel to write more code in "iterate" than in SERIES. And "iterate" is more flexible and more in line with the imperative semantic of some parts of CL.
4:34:16
EdLangley[m]
I think the sort of implicit stream-fusion SERIES does ends up being pretty limited in CL
4:35:14
EdLangley[m]
I've been experimented with transducers (from Clojure) that work more explicitly by passing a continuation around, and I think they're a better fit for lisps
4:40:14
mzan
Another thing I didn't liked to CL, it is that there is some lack of basic data-structures. In Haskell there is a rather efficient IntMap for example, and other data structures. C++ has plenty of them.
4:40:36
EdLangley[m]
The trick behind them is pretty simple: https://twitter.com/fwoaroof/status/1337667255727886337
4:47:16
mzan
ahhh "(1+ ...)". I din't know there were this function, but I suspected there were something of similar! :-)
4:50:41
mzan
EdLangley[m]: I don't know TRANDUCERS, but you example seems anti-intuitive to me. You are usinng a "reduce", but you pass a function that creates a stream (a vector in this case).
4:51:26
mzan
In your example, "compose" apparently do not work on streams using fusion, but only on the entire result.
4:53:47
mzan
In my ideal world, I would like stream transformers with an optional internal state, that can be fused. Then some final reducers.
4:53:59
EdLangley[m]
So, functions like MAPPING return a function that takes a continuation as an argument
4:54:54
EdLangley[m]
This returns a function with the signature you'd pass to REDUCE: (ACC NEXT) -> whatever
4:55:46
EdLangley[m]
This function, instead of building up a result with an explicit constructor, calls RF and passes an appropriate value of ACC and NEXT to it
4:56:09
EdLangley[m]
So, for MAPPING, this means something like (funcall rf acc (funcall transform next))
5:01:06
mzan
I don't know CL enough for understanding all your code. But it is usefull reading it for me.
5:04:08
EdLangley[m]
But (compose (mapping f) (mapping g)) doesn't build up an intermediate collection
5:04:35
moon-child
i.e. instead of (compose (mapping f) (mapping g)), you can say (mapping (compose f g))
5:05:24
EdLangley[m]
With a full library, you can do like: (compose (mapping #'1+) (filtering #'evenp) . . .)
5:05:58
EdLangley[m]
Basically, any operation that can be expressed through the lambda you pass to REDUCE, you can do this way
5:06:38
EdLangley[m]
Yeah, but the point is to preserve the (mapcar (lambda (b) ...) (mapcar (lambda (a) ...))) style
5:07:58
EdLangley[m]
This also abstracts from the concrete result type and from limitations like "the input sequence must be finite"
5:08:39
EdLangley[m]
You can express an operation once and pick whether it builds a list, a vector or puts results on a channel of some sort at the use-site
5:08:52
moon-child
my primary exposure to this sort of style is apl (not clojure), which is very strongly oriented _away_ from streams
5:08:54
mzan
EdLangley[m]: SERIES are composable, in the sense you can reuse a complex SERIES definition as starting point of another SERIES. Is your paradigm composable?
5:10:45
mzan
so something like (defun even1+ () (compose (mapping #'1+) (filtering #'evenp)) can be reused, while a "loop" no.
12:04:04
gamaliel
Hi, does anyone have experience with the vgplot system? I don't know how to return a plot as a tk widget. When I run (vgplot:plot) it returns an empty string.