freenode/#lisp - IRC Chatlog
Search
20:49:41
rk[ghost]
hmm, i am currently using CLL. my typical strategy for reloading my program is to (quit) and then (load "file") again. i am working on ways to modularize and load bits and have it do things from within modules.. however, is there a REPL command to "unload everything" (to prevent clobbering) so to avoid quitting and returning back to shell?
20:50:51
dlowe
rk[ghost]: many times you can reload source code without even stopping execution of the program
20:51:12
rk[ghost]
dlowe: i just don't want to remove extra variables in the debugging process. would be really annoying to be doing things and then find out it is because something old was still loaded in.
20:51:55
dlowe
rk[ghost]: yeah, that does happen. The usual method of development is to use "system" files like asdf that can track what files have changed
20:52:17
rk[ghost]
i see.. i will probably get there in time, but sometimes it is useful to know the hacky solutions XD
20:52:19
dlowe
but you can also compile and load individual functions and variable declarations into your running image
20:52:30
_death
rk[ghost]: then you have a good idea what you just redefined and what is the current state of the system should be
20:52:30
slaterr
dlowe this was forcefully asserting my stylistic opinion, just so you can tell the difference. as opposed to just explaining why I'd prefer clojure-like macro, when being told that I shouldn't
20:52:57
rk[ghost]
right but for instance what if the second run of a file doesn't have a defparameter *var*..
20:53:12
rk[ghost]
in such case i wouldn't expect *var* to be visible anymore, but yet it should be, eh?
20:54:55
rk[ghost]
slowly i am attempting to have my modules have "upgrade" functions like in OTP.. i'll probably eventually try to migrate things to lisp-flavoured-erlang XD
20:55:36
rk[ghost]
plus, then i would have to migrate things like Hunchentoot, which i don't fully understand.
20:56:00
dlowe
slaterr: it can really suck to feel piled upon, but there's a lot of different opinions in the channel, and I was just saying how much I liked the (shorter) plambda
21:00:01
slaterr
dlowe yeah, one second you liked shorter plambda, then next second you recommended an even longer than necessary lambda variant. it seems you just like to argue for the sake of it
21:01:46
rk[ghost]
... not having luck with the favicon.. just aesthetics, so i guess i will just abandon it..
21:05:45
dlowe
slaterr: I figured there was an understanding that these example bits of code were stand-ins for something potentially more complex, where a longer name would have value, contrary to your assertion that the specification of the argument was completely lacking in worth.
21:06:28
dlowe
and I have seen a lot of complex code that used single letter a-z variable names and it was terrible
21:07:02
slaterr
then your understanding was poor. and if function arguments warrants a verbose name then it shouldn't even be a lambda
21:08:09
slaterr
a-z variable names are excellent in very short functions. your proposed variable name was several times longer than the useful characters in the body of a function
21:09:13
slaterr
and you have to repeat variable name twice.. completely drowning the actual useful code in that snippet with unnecessarily long variable names.
21:09:56
_death
right, there are many times where a lambda expression is stylistically suboptimal.. and using something like #(... % ...) only makes it more difficult to recognize
21:11:53
slaterr
_death only if you are unfamiliar with the syntax. and the same argument can be used against any user-defined macro with non-standard naming convention and semantics
21:14:51
_death
every abstraction has a cost, and such crutches (and clojure has more of them, unfortunately) add up.. they help keep the code short at the price of hiding more useful abstractions
21:17:43
_death
so locally they seem nice (if you don't mind cryptic names like "%" or "->") and short, but overall they get you boilerplatish low-level code..
21:17:44
slaterr
what more useful abstraction would you use here? we are just passing a 3 character function to map
21:19:20
_death
slaterr: your example is a toy example, so your toy solution looks clever.. instead of trying to come up with something better for the toy example, I am just sharing my experience with such things
21:20:44
slaterr
a toy example? so you never had to do some simple operation to a list of things? you never use map?
21:21:22
_death
slaterr: so my experience tells me that a plain lambda there is OK.. and then when there's more code and it things get more complex, it's easier to see the patterns
21:23:13
slaterr
so we agree that # is better at lambda's job, than lambda. creating simple, short functions on the fly
21:23:22
_death
so instead of trying to optimize lambda syntax, keep it plain and optimize when it counts
21:24:32
pfdietz
Don't know if this was mentioned: https://github.com/eschulte/curry-compose-reader-macros
21:25:38
_death
slaterr: for reading, I do use pretty-lambda which substitutes the greek letter for the word
21:26:01
slaterr
pfdietz that is nice. I'd argue even nicer if you are just using lambda or # to emulate partial application
21:32:25
slaterr
{+ 1} syntax for partial application comes very close to haskell's (+ 1). it also supports positional arguments, and function composition. a lot nicer and more powerful than #'s
21:35:50
pjb
slaterr: if you publish your sources (eg. to quicklisp), then yes, if you do it naively.
21:36:28
pjb
slaterr: the point here is that LOAD specifies that the file is loaded in the context of a (let ((*readtable* *readtable*)) …)
21:37:11
pjb
Instead, you must SET the *readtable*. (eval-when (:compile-toplevel) (setf *readtable* *my-file-readtable*))
21:44:56
pfdietz
Both LOAD and COMPILE-FILE bind both *PACKAGE* and *READTABLE* (to themselves) before processing the file, so changes to either during the load/compile do not escape.
21:46:02
pfdietz
Changes as in changes to the variable, not changes to the package or to the readtable objects.
21:51:07
fiddlerwoaroof
An alternative to messing with the lambda syntax is to define higher order functions that combine other functions to produce the lambda you want
21:57:21
_death
fiddlerwoaroof: this reminded me of this snippet https://gist.github.com/death/34d4bd499b323016fa65be5ba72fabc1
22:00:53
rk[ghost]
ha.. gee.. changed the .ico to a .png.. maybe ff doesn't support the x-icon type.. it just worked.. yaay:D
23:10:48
fiddlerwoaroof
_death: yeah, I have a library that implements this pattern: https://github.com/fiddlerwoaroof/data-lens
23:10:59
jmercouris
let's say I've done (ql:quickload :some-library), how can I get the system-version loaded
23:11:16
fortitude
ASDF defines systems as a tree of components; each component might be something more specific like a module or a file definition
23:16:19
fiddlerwoaroof
(defining methods for generic functions you don't own for classes you don't own)
23:17:14
fiddlerwoaroof
On the other hand, "someone" could define a library for querying ASDF for various bits of information
23:18:57
fiddlerwoaroof
(to be clear I'm not referring to anyone in particular, just making a joke about every annoying problem being someone else's problem)
23:19:29
fiddlerwoaroof
It's the kind of thing I'm interested in, but I never seem to have the time for
23:20:14
fiddlerwoaroof
At a very simple level, just define some functions (asdf-query:system-version :alexandria)
23:21:13
jmercouris
thanks, have you seen the branch? it is quite different than the current incarnation
23:21:21
fiddlerwoaroof
I don't know if you've run into the little bug where the start-swank command seems to kill the app on mac
23:32:38
mrpat
What is the best package for downloading https sites? It seems cl+ssl is messing with my Drakma and Dexador.
23:36:31
jcowan
No, Smalltalk and Ruby are the kings of monkey-patching. You can do it in pretty much any dynamic language, but in a lot of langs the culture won't let you.
23:40:12
fortitude
mrpat: drakma and dexador should both work without having to set up cl+ssl first, but cl+ssl can have issues on some systems (windows)
23:40:31
fortitude
I think dexador bundles its own certificate store, which should avoid most of the problems if its recent enough
0:02:27
fiddlerwoaroof
A former coworker wrote a nice blogpost about the problem: https://lexi-lambda.github.io/blog/2016/02/18/simple-safe-multimethods-in-racket/
1:21:28
pillton
That is quite a restriction. It also completely ignores the point of generic functions i.e. separating operations from state.
1:24:21
fiddlerwoaroof
pillton: not really, I believe beach, for example, has mentioned similar things.
1:24:50
fiddlerwoaroof
In most cases you're either defining a new protocol or you're defining a new implementation of the protocol
1:25:18
fiddlerwoaroof
In the former case, since you defined the generic function, you can define methods that specialize it however you want, since you own the protocol
1:26:01
fiddlerwoaroof
In the latter case, you should only specify how your new class interacts with the pre-existing protocol, otherwise you might change the contract of the protocol for other classes.
1:37:55
makomo
_death: interesting writeup regarding On Lisp, thanks. i'll give it a proper read when i get the time
1:39:05
makomo
hm, where's does one draw the line between using designators vs. using actual objects (that the designators designate)?
1:40:41
makomo
for example, in the case of ASDF, most of the time you can pass designators such as :hello or "hello" instead of the actual system object representing the system hello
1:41:02
makomo
but then comes asdf:component-version which takes a system object instead of a designator
1:41:37
makomo
when designing a library, where draw the line between accepting designators and not doing so?
1:46:43
makomo
pillton: hm, i don't understand. by "representations" do you mean designators? if so, why?
1:48:07
pillton
Bah. http://www.lispworks.com/documentation/HyperSpec/Body/26_glo_p.htm#pathname_designator
1:51:15
pillton
The string "/tmp/hello-world.txt" is an equivalent representation of (make-pathname :name "hello-world" :type "txt" :directory '(:absolute "tmp")).
1:54:49
makomo
oh, i think i see the point of your guideline now, which was in favor of designators in that case
1:55:16
makomo
what if you have 2+ representations and they do share a common class, but that class is not a common class for the object they designate?
1:55:52
makomo
you still have a designator but it is essentially only the common class of the 2+ designators
1:56:21
makomo
however, that wasn't really my question. i'm more wondering about API design, i.e. *when* to actually accept such designators and when not to
1:56:46
makomo
i.e. whether to constantly worry within your API that a designator might be passed in, or to cut it off at one point and say "i want an object of type X now, no more designators"
1:57:17
makomo
Bike: i see, so basically a "layered" approach? the highest-levels parts accept them and then lower (library) levels don't?
2:33:04
fiddlerwoaroof
It's like input validation in a web app: you want to validate and sanitize the user-submitted data asap so you don't have to worry about all the nonsense a user will throw at you.
2:40:43
skidd0
when creating an asdf system, how can I set up some special variables on system load?
2:44:05
fiddlerwoaroof
It depends on what exactly you want to do, but I think the write thing is an :around method on perform that is specialized one your current system and some operation such as load-op
2:44:51
fiddlerwoaroof
skidd0: this is probably better: https://common-lisp.net/project/asdf/asdf.html#Controlling-file-compilation
2:48:32
fiddlerwoaroof
I think that should work out fine, something like (defun main () (initialize-hash-lib) (do-stuff))
2:49:26
skidd0
tho checking if *special* is set is probably just as time consuming as resetting the *special* anyway
4:11:49
elderK
Have been working on my structure-thing. God damn I have a lot of helper functions for it :P
4:17:15
fortitude
elderK: technically, no; a structure can have several representations including a plist or other non-class value
4:17:41
fortitude
if you're willing to require that the struct be class-based, then I think then slot-value is safe to use (not 100% sure though)
4:21:58
beach
The existence or not of a particular slot is an implementation detail. A protocol is defined by functions and initargs.
4:55:01
elderK
From what I understand, it allows us to provide a form that can reconstruct some literal at load-time.
4:55:03
beach
It's rare that you need it. Only when you need to save application objects in a FASL so that you can create a similar object when the FASL is loaded.
4:56:00
elderK
beach: I've seen it used in a way that suggests it can be used to somehow store data that the compiler is using when generating a macro expansion, into the expansion.
4:56:13
elderK
Like, binary-types creates a bunch of record objects - then patches them into the expansion as literals.
4:57:32
beach
Yes, I can see that. Any time you compile something that contains literal objects that the system does not know how to represent in a FASL, you need this kind of mechanism.
5:45:27
beach
Actually, that's an interesting topic. Talk to me about the usefulness of FASLs now that computers are so fast that you can compile the code when it is LOADed without any significant performance impact!
5:46:29
no-defun-allowed
here's one: macros can do anything normal functions can so what if a macro does a lot of processing on its arguments?
5:47:43
p_l
beach: FWIW, on my pretty recent hw I see considerable real time difference between loading code from FASL and compiling
5:48:59
no-defun-allowed
otoh, asdf or quicklisp loads fasls when your system definition is absolutely broken or something like that and it's annoying
5:49:23
no-defun-allowed
eg: you move your toplevel stuff to src/ and the files are no longer there cause you neglected foo.asd and it loads from the fasls
5:50:20
shka_
beach: modern systems have constantly increasing number of dependencies and compilation time adds
5:51:29
beach
shka_: Again, you are talking one execution at the beginning of a session that should typically last months, unless your computer crashes the way mine does.
5:54:40
no-defun-allowed
wait no i don't but i probably should cause at least it's easier to install alternate drivers which might not crash on it
5:54:56
beach
p_l: I don't understand. If you work on some system, you would typically edit a single file at a time, then C-c C-c or run ASDF which would then only compile and load one single file. No?
5:55:16
no-defun-allowed
i'd consider leaving a lisp "running" if s-l-a-d somehow kept the slime connection
5:57:12
no-defun-allowed
cause i don't leave emacs running all the time cause i'm still stuck in a "workspaces don't exist" mindset sometimes
5:57:54
no-defun-allowed
cause i was brought up on winxp where the closest thing was a hack which "grouped" programs and windows and would let you minimize and reshow groups
5:58:40
beach
Let me summarize: p_l is quitting the Common Lisp system for no reason. shka_ upgrades several times a day, and no-defun-allowed has not considered leaving the Common Lisp system running. :)
5:59:36
no-defun-allowed
also sometimes i need to purge out old code since i'm pretty bad at leaving a system half broken and the saved code's fine
5:59:39
shka_
actually the most frequent reason for restarting lisp for me is lost invariant of GC :P
6:00:02
no-defun-allowed
on that note, is there a way to replace a :BEFORE or :AFTER method with slime like you would with a defun?
6:00:28
no-defun-allowed
from experience it just tacks another one on, but i do understand figuring out which to replace may not be trivial
6:01:08
pjb
in the meantime: cl-user> (uptime) / uptime: 11 days, 15 hours, 6 minutes, 24 seconds. / 1004784
6:01:56
beach
Anyway, I would like to thank everyone for this VERY INTERESTING discussion. I now have a very good picture of why people need FASLs.
6:02:24
no-defun-allowed
i've heard ccl on arm has had problems with threads and gc, but i don't know much about that other than my research on cl on pi
6:02:29
beach
shka_: Are you saying your Common Lisp system does not have first-class global environments?
6:03:11
no-defun-allowed
same thing here with tests, i often spin up a second lisp in a terminal to load tests.lisp and see if it loses or not
6:03:52
no-defun-allowed
after hacking around with aeth to get gitlab ci working on cl, i get a bit too pissed off when ci fails
6:04:57
no-defun-allowed
also testing the tests is important since i did a lot of prototyping of my admittedly very simple fuzzer
6:04:57
beach
Again, thanks to everyone for this very enlightening discussion. I am a bit wiser than I was 15 minutes ago.
6:06:55
no-defun-allowed
come to think of it after a recent slowdown in my programming ci has very destructive psychological effects
6:07:18
no-defun-allowed
you end up just doing the bare minimum required to pass the tests sometimes
6:07:18
fiddlerwoaroof
beach: I generally have one lisp session that I use for most of my projects and then one or more that I use for things I don't want to accidentally kill
6:07:54
fiddlerwoaroof
However, I have a tendency to hit the heap size limit at the worst possible times
6:11:04
fiddlerwoaroof
As far as stale-code goes, I've found that (delete-package :foo) or (rename-package *package* (format nil "~a.OLD" (package-name *package*))) solves most of those issues
6:12:41
fiddlerwoaroof
As far as quicklisp is concerned, I think ironclad takes about a minute to compile, as does mcclim if I'm compiling it fresh
6:27:40
beach
fiddlerwoaroof: Yes, that's my impression as well. And I don't load McCLIM that often. It is typically already loaded in my current session.
6:43:37
p_l
beach: which is something I referred to earlier as something that would help immensely ;-)
6:44:50
p_l
beach: also, sometimes I want to ship fasl because I get to control compile time environment
6:45:05
fiddlerwoaroof
I find that I can deal with the lack of first-class global environments in most cases by strategically renaming packages before recompiling and loading the files I'm interested in
6:45:34
beach
p_l: My current plan for SICL is to use the AST as a FASL, which would have the same characteristics.
6:45:40
fiddlerwoaroof
But, I tend to write my code to avoid compile-time side effects as much as possible
6:47:51
fiddlerwoaroof
That would mean that, in theory, you could use the same FASLs on different architectures, though
6:48:43
p_l
My dream feature would be an "image fragment" where code could be located both in three different forms at least - source, AST, machine code, all possibly linked so I could edit the source that came with binary
6:49:01
beach
p_l: The AST format fulfills the requirement that the Common Lisp HyperSpec has on file compilation.
6:49:58
fiddlerwoaroof
Yeah, I've been hoping to find time to do some of the programmer conveniences
6:51:12
p_l
In a sense, the idea is that a) source code is just an object in the image b) you can export portions of the image and import them in different environments
6:51:39
fiddlerwoaroof
I've recently been experimenting with using logical pathnames inside the defsystem's :pathname to see if I can get better source-finding capabilities without too much work
6:52:53
fiddlerwoaroof
one thing that occurs to me is that SQLite has a mode where it can append a database to any random file and so, since most executables ignore random junk at the end, I've thought it would be interesting to have an attached sqlite database for holding things like source code and other instance metadata
6:53:34
fiddlerwoaroof
obviously, the end goal would be something that didn't depend on a non-lisp library, but I thought this might be an easy way to get a proof of concept working
6:54:40
fiddlerwoaroof
The issue I have with something like that is that then the thing I'm talking about is implementation specific
6:55:12
p_l
Unfortunately most unix systems don't support resource forks so certain things I'd like to see for keeping such db write-able require splitting file on write
6:55:57
fiddlerwoaroof
Yeah, my inclination would be something like the program would check if the executable is writable on start up and, if not, it would dump itself somewhere writable and restart itself
6:56:41
p_l
They have some nice Quality-of-Life stuff for supporting living with images, specifically the Pharo Launcher
6:56:41
fiddlerwoaroof
And then, the next time you run it, it would find the writable version and delegate to that.
6:59:30
fiddlerwoaroof
I get the impression that, as a rule, Pharo uses Monticello and Metacello for vcs
7:09:34
fiddlerwoaroof
Is there any way to compile a string using exactly the same logic that would apply as if you wrote the string to a file and compiled the file?
7:14:05
fiddlerwoaroof
The _other_ idea I had would be to check a git repository out into memory and then change ASDF to know how to load a system from something like a hash-table of filename -> contents
7:14:53
fiddlerwoaroof
But, the standard specifies file compilation to have specific behavior for toplevel forms that, afaict, COMPILE doesn't enforce
7:34:57
flip214
ITERATE's FINDING doesn't seem to return multiple values... or am I doing something wrong?
7:35:47
flip214
ah, https://common-lisp.net/project/iterate/doc/Finders.html#Finders says "and *the* value of expr is returned" [emphasis mine]
7:42:00
beach
Graduates with a masters degree don't know much about programming language implementation. Plus, our system imposes a 3-year limit for a PhD. There would not be enough time for the student to learn enough about Lisp, programming language implementation, compilation, etc. in 3 years, let alone to write the journal papers that would be required for that student to get a job afterwards.
7:46:53
p_l
My criteria were the ability to do the PhD without joining on-site as normal full time student, and freedom in choice of topics
8:03:15
p_l
beach: in Poland, it's theoretically doable but you have to get through administrative opposition and essentially have a promotor willing to tackle it
8:19:08
p_l
some of it is personal ambition and growth. Frankly speaking what I do for a living tends to have people without degrees often
8:21:02
p_l
though thanks to "West" tending towards BSc instead of Master's as first degree I already have quite a bit of advantage there
8:21:13
jackdaniel
curiousity of a day: https://gitlab.com/embeddable-common-lisp/ecl/issues/458 (*print-case* specification isn't really well integrated with *readtable-case*, there is a cleanup issue for that though)
8:24:19
loke`
jackdaniel: In Maxima, maxima symbols are mapped to Lisp symbols by prefixing them with $ and using “invert” readtable-case
8:24:46
jackdaniel
heh, I need to take my time some day to study maxima (at least from the user perspective)
8:25:18
loke`
In Climaxima, to be able to display Maxima symbols properly, I simply install a readtable with readtable-case set to :INVERT. That fixes everything, but if I read your summary properly, that's just because I'm using SBCL, and different behaviour could be seen on other CL's?
8:25:28
jackdaniel
only interaction I had with it was fixing bugs discovered by maxima developers (they are very helpful and provide detailed test results before each release!)
8:26:15
loke`
jackdaniel: Right, but when I have the readtable installed, it also affects printing. At least on SBCL.
8:27:39
loke`
jackdaniel: OK. So is there any way I can ensure better compatibility with all CL's? What if I set *print-case* to :INVERT as well, will that fix it?
8:28:37
jackdaniel
loke`: no, because *print-case* is specified as if only :upcase was a current readtable-case
8:31:38
jackdaniel
http://www.lispworks.com/documentation/HyperSpec/Issues/iss286_w.htm this cleanup issue provides more information about how this could be solved
8:32:14
loke`
To me it's more than a curiousity. I seem toi have actually found myself in this territory. :-)
8:34:13
jackdaniel
from another practical perspective: print-case as it is specified doesn't play nice if programmer wants to work with so-called "modern" syntax (name taken from allegro and adopted in named-readtables), that is with preserved case
8:34:49
jackdaniel
it just gets in a way with all these vertical bars (but it doesn't sting *that* much)
8:36:25
jackdaniel
either way: someone eager to help with ECL may take this issue and implement the cleanup issue :-)