freenode/#lisp - IRC Chatlog
Search
15:26:35
Bike
i know in my case i started out learning (an oversimplified version of) what C++ does and expected lisp to be similarly confusing
15:34:45
_death
to further confuse people, you can also claim that Lisp has pass-by-name with macros :)
15:35:36
ogamita
or even with functions: (defun f (x) (set x 42)) (defvar *x* 33) (progn (f '*x*) *x*) #| --> 42 |#
15:37:56
_death
dlowe: (defun swap (a b) (rotatef a b)) (let ((x 1) (y 2)) (swap x y) (list x y)) => (1 2)
15:37:56
dlowe
if you pass an object to a function, they get an object that is EQ to the object passed, and mutating that object mutates it in all contexts
15:40:06
ogamita
(defun swap (a b) (rotatef (symbol-value a) (symbol-value b))) (let ((x 1) (y 2)) (declare (special x y)) (swap 'x 'y) (list x y)) #| --> (2 1) |#
15:40:12
_death
dlowe: when you pass an object to a function, a new binding is created (the reference to the object is copied)
17:36:47
sjl
Is there some way to do something like (:module "problems" :components ((:files "*.lisp"))) in ASDF, rather than listing out every file by hand?
17:37:25
sjl
Usually I don't mind the listing, but for stuff like Project Euler, Rosalind, Avent of Code, adding every problem file to the .asd file by hand is tedious.
17:42:07
fortitude
#.(mapcar (lambda (f) (list :file (namestring f))) (uiop:directory-files #P"src/")) or similar
17:42:51
fortitude
looks like UIOP:DIRECTORY-FILES returns absolute paths, so that won't quite work as-is
17:43:04
sjl
Yeah, I considered that, but was worried I'd need to do some magic to make sure the current directory at .asd read time is the same one as it's gonna be loading the components from
17:43:29
fortitude
that could be a problem, but for something you don't plan to distribute you might not have to care
17:44:57
jdz
I wonder if there's a way to override/implement some EQL method (specialised to particular system) that would generate the components...
17:45:21
sjl
jdz: although, that takes a system as an argument, and I'd need to use it as I was READing the system... so the system can't really exist yet
17:45:36
fortitude
sjl: you could also write some code to create the file list and paste it into your system file, if the list isn't going to change much
17:46:08
jackdaniel
I'd define a new component type subclassing module, for instance harvesting-module and work from that
17:46:26
jdz
Or maybe you'd create a class AUTO-POPULATED-SYTSEM, and make your system inherit from that.
17:46:37
sjl
jackdaniel: that's probably the correct way to do it, though ASDF's use of CLOS frightens me
17:47:23
sjl
jackdaniel: I mean, it's just for silly code problem websites, so I'm not super concerned
17:47:51
fortitude
verisimilitude: sjl wanted to dynamically include a list of :file components in an asdf system
17:50:03
fortitude
or extending asdf, as jackdaniel suggests -- I made a build system for another language that way once; was a lot of work, but it's certainly possible
17:52:05
sjl
But yeah, I'd imagine making a :greedy-module component is probably the Right Way to do it
17:52:33
fortitude
sjl: that might also be useful for other people (but it's a lot harder than the other hacks, if you're just concerned about convenience in your own projects)
17:56:24
pfdietz
I had a problem once with uiop:run-program not working properly with a certain shell. Had to wrap the shell command being executed in parens.
18:36:42
sjl
jackdaniel: neat. So to package this up, I'd make a (very small) asdf-auto-module system, then have :defsystem-depends-on (:asdf-auto-module) and then (:components (:auto-module "problems")) would Just Work?
18:38:50
Xach
rpw has written about a living system with which he would register the files he's working on and provides some terse repl commands to reload things in progress
18:41:18
jackdaniel
Xach: I don't understand, how is this different from (say) binding (asdf:load-system 'living-modules) to a symbol-macro |R|?
18:44:27
jackdaniel
uhm, thanks for explanation. I don't see much value in that, but maybe I lack some context/examples or it doesn't match my workflow
18:45:47
Xach
jackdaniel: he uses vi and a separate repl so he has incentives to make the repl more supportive and intelligent. that's one of the ways.
18:46:42
Xach
i don't always enjoy the asdf-as-recipe model where you write a system definition and then use asdf to do a ton of sometimes-opaque work and at the end you get a working system, except when you don't and you have to go back to fiddling with recipes.
18:52:29
Xach
i think dribble is the vestige of a more powerful, supportive system that could not be wedged into CL
19:22:07
jasom
FWIW when I used vi and only used slime as a debugger/repl, asdf:reload-system was my friend.
20:19:08
aeth
Hmm, it looks like one part of this one loop needs a really complicated GOTO for performance reasons so 8 things can share one implementation. Oh wait, I can just use a local function closure. Thanks, Sussman and Steele.
20:28:24
aeth
Paris? Everyone knows the capital of Lisp in France is Bordeaux because that's where they make the Lisp threads that they then export to the rest of the world.
20:33:34
aeth
Fun fact: they picked Bordeaux because it's a port city so it's easier to export the libraries that way.
20:36:34
no-defun-allowed
"I can't live without it, I just love it! Oh my gosh I don't even buy pipes with other SBCL instances anymore. If you're gonna create your threads or any mutexes, you'll be out of your mind not to own one of these. All I can say is Bordeaux! Threads!" ~Vince Offer on bt
20:43:18
no-defun-allowed
I thought of another optimization to speed up CL-as-an-emulator-translator too, you could try to lift registers out of the register array and hopefully they'd go into machine registers.
22:01:38
newbie1
hi all, Given that use-foldr consumes a (listof Nat): (define (use-foldr L) (foldr myfun "some-str" L)) What is the contract for myfun ? What is the contract for use-foldr ? can someone guide me?
0:30:21
griddle
Does anyone know of a good reading source for how lisp JIT compilers or ahead of time compilers work? I'm mostly interested in how scoping is implemented
0:33:19
Bike
The most obvious way is that the (lambda (y) ...) produces a "closure", which stores the binding of x along with the function.
0:37:53
griddle
and you'd have some kind of feature to lookup information in that structure? Or would you know ahead of time where in the structure that value lives
0:47:14
aeth
griddle: Naively, there could just be a defstruct to create a structure-object for every scope except the global one. Gensym its name to avoid the problem with redefinition.
0:47:21
jasom
griddle: In a compiled implementation, a lexical binding is just a mapping from an identifier to a location (i.e. lexical bindings do not need to exist in a meaningful way at runtime, only at compile time).
0:47:59
aeth
(I say structure-object because they're simpler and they can have inline accessors, or something like that. i.e. the location is known to the compiler at compile time)
0:48:23
Bike
i think if griddle doesn't know what a closure is they might be unfamiliar with defstruct.
0:49:02
griddle
I've implemented a lisp interpreter in the past, I'm just looking into how things like lexical scoping is done in a JIT if you can define different variable names at runtime
0:49:10
jasom
what usually happens is compilers have an expensive binding implementation that works in all cases and lives on the heap, but then a fast binding implementation for when a variable is never closed over (or is only closed over by lambdas that don't escape the heap).
0:49:53
jasom
griddle: for the most part, compiled implementations of lisp do not allow manipulation of lexical bindings at runtime
0:50:52
jasom
dynamic bindings have a defined lifetime at runtime, and those can be accessed via symbol-value.
0:52:23
griddle
yeah in past I've just had a really slow implementation with a recursive scope lookup of dynamic bindings
0:53:16
jasom
griddle: for variables that are never closed over, the value can be stored in a register. For variables that are closed over by lambdas that don't escape the dynamic scope, it can be the stack. For variables that are closed over by lambdas that might escape the dynamic scope, they must be stored on the heap.
0:53:44
jasom
griddle: I think you have dynamc and lexical backwards. Dynamic bindings are trivial to implement with global variables and unwind-protect.
0:56:55
aeth
jasom: Absolutely (re: expensive and fast implementations). The variable isn't even guaranteed to exist unless (debug 3)
0:57:22
aeth
On the plus side, that means that there's no (runtime) cost to naming intermediate steps if you want to
0:58:07
jasom
griddle: if you're familiar with compilers for less dynamic languages, all the approaches used there for temp allocation work just fine for any variables that are never closed over.
1:02:57
verisimilitude
Well, I enjoy the colorful phrasing RMS used, comparing the stack to a government agency.
1:03:17
verisimilitude
Put simply, treat the stack as a stack until it can no longer be treated as a stack, in which case it was never really a stack at all.
3:06:13
jcowan
I understand the idea of conditions with restarts, such that the condition-catcher can choose which restart to invoke, do a snippet of code set up by the signaler, and then either return or do a non-local exit