freenode/#lisp - IRC Chatlog
Search
4:29:57
montxero
Starting out with the SCIP videos but doing the exercises in common lisp. Fun so far...
4:31:28
montxero
every now and then, I have to do some mental gymnastics to get over the single/dual namespace difference
4:33:56
beach
Yeah, it can be tricky. Nowadays there is Portacle that packages those things conveniently.
4:34:31
beach
Make sure you use the slime-indentation contribution for SLIME. At least I *think* that is still only a contribution and not the default.
4:40:59
beach
montxero: Also, the function that you thought would be local seems to be using tail recursion with an accumulator. That is also a Scheme-ism because in Scheme, iteration is really tail recursion under the hood. In Common Lisp, you would use iteration instead, especially since Common Lisp does not guarantee tail-call merging.
4:44:35
montxero
I just noticed... not sure why that happened. https://pastebin.com/EG2FGJby just repasted the original
4:45:43
beach
It may have to do with TAB characters in your source. Pastebin may not handle them right. I suggest you make Emacs use spaces all the time. Other tools don't do TAB characters very well either.
4:47:51
montxero
So, labels / flets rather than nestd defuns.. Is there a particular reason for that? like the functions leaking out to global scope?
4:49:26
beginner_supreme
Example reference: (defun add (a b) (+ a b)) --> (add 1 2) => 3 is the usual way. (labels ((add (a b) (+ a b))) (add 1 2)) => 3 is the labels way.
4:56:41
montxero
Okay cool... I'm reading clhs for flet and labels. This portion: "labels is equivalent to flet except that the scope of the defined function names for labels encompasses the function definitions themselves as well as the body." seems a bit opaque to me; almost like it is hiding a very subtle warining
5:01:16
montxero
Oh!!!!!, so if I want to define a recursive function inside the scope of another function, I would be better off using labels (rather than defun). If I were to define said recursive inner function with FLET, on calling the function, I will get a symbol (unbounded / undefined) error or someting to that effect. Is that it or am I missing something else?
5:03:42
beach
Right now I am having my coffee in order to wake up, so any more taxing intellectual activity shall have to wait anyway.
5:09:24
montxero
beginner_supreme: Thanks for that. The namespace demo captures a lot of the problems I've encountered
5:09:34
beach
beginner_supreme: It is not common to use #'(lambda...) anymore. You can just use (lambda ...) instead.
5:11:46
beginner_supreme
That took a while to write up because I still haven't learned enough emacs.
5:16:25
beach
montxero: If you know how to program in other languages already, PCL may be a better alternative to SICP.
5:16:34
minion
montxero: look at PCL: pcl-book: "Practical Common Lisp", an introduction to Common Lisp by Peter Seibel, available at http://www.gigamonkeys.com/book/ and in dead-tree form from Apress (as of 11 April 2005).
5:18:10
minion
Are you a bot: An error was encountered in lookup: Parse error:URI "https://www.cliki.net/Are you a bot?source" contains illegal character #\ at position 25..
7:02:04
jdz
It depends on what you want to achieve. But (defun coerce-all (type &rest args) (loop while args collect (coerce (pop args) type))) should work.
7:04:16
pillton
You are probably drawn to common lisp because of the power of macro functions. The irony is that macro functions should be the last thing you use.
7:12:54
beach
littlelisper: Make sure you practice cases that actually need macros. Otherwise, you will get into all kinds of strange coding practices.
7:15:03
beach
Interestingly, since SICP is Scheme and Scheme does not have macros, that might be the wrong source for practicing macros.
7:18:25
beach
littlelisper: Macros are used only when the evaluation rule for functions will not work.
7:23:44
pillton
littlelisper: I find the best explanation of the difference between functions and macro functions is in section 3.1.2 of the hyperspec. It also helps highlight the difference between form syntax and character syntax.
9:09:20
shrdlu68
In Hunchentoot, within the body of an easy handler, when I log to *standard-output*, *terminal-io*, or *error-output*, the output appears in the *inferior-lisp* window rather than, as I expect, the slime repl.
9:10:24
shrdlu68
I guess hunchentoot is binding these vars locally to something else. How can I get the usual output to the slime repl despite that?
9:10:25
_death
it runs in a different thread where these variables aren't bound to slime output streams.. you can use a proper logging library, like log4cl
9:12:07
_death
there's hunchentoot:log-message* .. if you think hunchentoot support for logging is sufficient
10:17:21
jmercouris
I'm working on an interactive command prompt. I can complete/tab complete command names. I'm now working on completing command
10:17:33
jmercouris
I would like each argument to be able to provide its own set of completions to guide the user.
10:18:28
jmercouris
the only thing I've thought of so far is defining separate functions for each argument completino
10:19:11
jmercouris
so something like (define-command command-x (arglist)) followed by (command-x-arg1 () ...completion logic..) (command-x-arg2 () ... completion logic...)
10:19:33
dim
jmercouris: did you manage to write the README first? (RDD method, I like it), that is, how are you going to use it, what do you expect to see as completion choices in several situations?
10:21:18
jmercouris
I have one concrete application in mind, but I don't know how the application will evolve
10:22:00
jmercouris
I guess I will spend some more time thinking about how the product will actually be used
10:22:16
dim
my usual technique for that kind of question is a 1h walk at good pace (walk fast enough that you could not sustain a chat at the same time, that's how the brain is best oxygened)
10:23:52
dim
going for a walk only gives good results when you understand the problem clearly enough, which looks like it's the case here
10:23:53
xificurC
A: how can I do Y? B: what is the real problem X? A: it is ... B: Ah ok, I suggest you go for a walk then
10:24:53
jackdaniel
jmercouris: McCLIM has commands which have types and interactor provides completions of various type (list, string, number etc)
10:25:39
jackdaniel
putting aside presentations and how buggy the whole mechanism is in McCLIM, design may be at least worth studying (CLIM II specification is fine if not too engineered)
10:50:20
loke
shka: Well, some things that should be simple is very hard. Other things are almost magically automatic. :-)
10:50:39
jackdaniel
it is a working software with bugs (as we know, none of Lisp software has bugs, so it must be an accident) and plans for the future
10:51:31
jackdaniel
if the question is: is there a hope you'll use it, then you must answer itself. if the question is: is there a hope it will work? then it works, like right now
10:51:41
loke
shka: I make a playlist: https://www.youtube.com/watch?v=AvC82EjoPYU&list=PL6AQVVynH5Dg3Wwpk3zNT962GntKfssje
10:53:00
loke
shka: Things like subexpression selection in the equations are automatic in CLIM, which is cool.
10:53:09
shka
jackdaniel: well, ideally, i think that McCLIM should work on major platforms (that would be osx, windows, x11 and wayland), require modest ammount of time to build usefull applications and don't be very buggy, given the scope, this task list appears to daunting
10:58:37
jackdaniel
shka: you basically present a wishlist, not something to justify queationing for any hope for the software, so I still don't understand
10:59:14
loke
shka: I think that's my biggest advantage to Wxmaxima, which, while doing proper maths rendering, looks quite bad.
10:59:24
jackdaniel
it is like if I had asked: is there any hope for lisp? I think it should be faster, work on more platforms and have first-class global environments implemented
10:59:38
loke
shka: Well, believe it or not, it's sthings like the completions popup, where I had to build everything from scratch.
11:00:05
loke
Also, being able to manpilate the graph (using the buttons) also took quite a bit of convincing CLIM ;_)
11:01:10
loke
shka: Just getting the commandline (“interactor”) to accept plain text was tricky to say the least.
11:01:35
loke
shka: The entire thing is deeply tied to the idea that your application is driven by a commandline which is a Lisp REPL.
11:02:13
loke
shka: In Maxima, input is onbviously the Maxima language, which meant that I had to reimplement the entire input loop.
11:02:56
loke
shka: For reference, here is the code to simply read the Maxima expressions on the commandline: https://github.com/lokedhs/maxima-client/blob/master/src/cmdline.lisp#L174
11:04:13
loke
shka: Another issue is that since it's inherently single-threaded, and the inptu loop is imperative, managing more than one input loop is incredibly hard
11:05:18
loke
shka: You can open a second window by running a separate thread, but there is zero support for interacting between them, so you have to build everything yourself. I don't even want to think about what it would take to implement drag-and-drop between windows.
11:06:10
loke
shka: Generally you should attempt to build you application absed on CLIM concepts, not try to convince it to behave like a “normal” GUI application.
11:07:57
loke
shka: THere are aspects of it that are really cool too, but I never mentioned any of those.
11:08:41
loke
shka: well, that was how the Lisp machine worked, and CLIM is basically a lisp machine interface :-)
11:09:40
random-nick
it's not really a REPL, it accepts program-defined commands too that are not lisp code
11:10:26
loke
and commands can be invoked not jst by typing them, but also by clicking buttons, or clicking on objects on the screen, where each object is an actual Lisp object
11:10:53
loke
shka: You don't have to type at all. You can expose all your commands as buttons or clickable “things”
11:12:44
loke
So in the maths renderer I built, each equation is a “thing” that renders as an expression. They consist of other “things” which are the subexpressions. There is also a translator that converts these things into text (which happens to be the maxima language form of the same equation.
11:13:29
LdBeth
ACTION I know it’s probably like asking “when will the next version of Common Lisp spec come out” (^O^)
11:13:46
loke
That's why you can click on a subexpression while typing a maxima command, and the nexessary code is autoamtically pasted. It's because there is a command translator that is applied when clicking which in that context.
13:51:52
flip214
p_l: digitally signed? via PGP or GPG? that's easy, just create your own key for "Peter Norvig" ;)
14:07:21
jackdaniel
certainly he is convinced, that python is a better choice for teaching as a language
14:10:46
p_l
I think he mentioned a bit of external reasons to deal with Python, and tbqh, Common Lisp did have a bit of problem with easily available implementations and their *distribution* among people
14:11:04
p_l
(at least from perspective of someone who didn't know anything about lisp at the time)(
14:13:01
dim
I've read that scheme is pretty good at teaching (syntax as in CL, also not so many batteries included, meaning students can try coding merge and other advanced stuff themselves rather than just calling the already provided feature)
14:17:21
jackdaniel
I do not understand what could be a reason, why scheme wouldn't be a good pick for (say) machine learning, but this is offtopic anyway
14:30:20
Satou
Hello! I have a question regarding user-defined packages. I've defined a package that I want to use in another file. http://termbin.com/tdeb
14:31:22
Satou
I compiled it and loaded it in another file using (load "ipfs"), but doing anything like (print (cl-ipfs:version)) doesn't really work. It tells me the package doesn't exist.
14:32:53
Xach
One immediate problem is the package name is "cl-ipfs" but for normal interoperation you would want it named "CL-IPFS".
14:33:19
Xach
Another problem is that you need (in-package "CL-IPFS") right afterwards if you want the subsequent symbols to be read in that package
14:33:44
Xach
Another issue is that you can't refer to "cl-ipfs:foo" unless foo is external in cl-ipfs, usually via an :export clause in defpackage.
14:34:31
Xach
but also, what shka says is right - it would be even more virtuous to make a system definition and go from there
14:34:36
beach
Yet another issue is that the indentation of the forms following DEFPACKAGE suggests that they are somehow in the scope of that package definition.
14:34:39
Satou
oh no shka, I just want to create the package and test it from the other file, my intention is not to glue toghether a lot of files
14:36:18
beach
Satou: The indentation of :method :post, etc looks like they are in the body of the LET.
14:36:40
shka
there is a decent tutorial on lisp packages that explains different issues people run into
14:36:57
Xach
Satou: i find it helpful to change my mindset and think that my project is the CL development system, and I am extending it by adding new definitions, with some organization of those new definition names by packages. the definitions are for functions, bits of data, classes, etc. and then i interact with it by calling functions while the whole environment is running, without stopping and starting much.
14:37:23
Xach
i have been in the land of "write a script in a file, run it, repeat" a little lately and it is a different mindset.
14:38:09
Xach
that is not only a stupid title, it includes stupid and sarcastic advice mixed in with the useful info. alas.
14:39:16
beach
Satou: For what it's worth, I totally agree with Xach, that the best way to think of your code is to imagine it extending an existing, executing Common Lisp system. Not that you start that Common Lisp system every time you want to run your code.
14:40:10
beach
Satou: Such an organization will help with lots of things like debugging, interactive incremental modifications, etc.
14:41:09
Satou
I see. However someone pointed out that I shouldn't use quicklisp and just define a package that relies on drakma and yason.
14:42:20
Satou
I would like to encapsulate it somehow, and access the functions I've defined through an entity.
14:42:34
beach
Satou: If I were you, I would write an ASDF system definition called, say cl-ipfs.asdf. I would have one file called packages.lisp and one file called cl-ipfs.lisp.
14:43:26
shka
https://github.com/sirherrbatka/documentation-utils-extensions/blob/master/documentation-utils-extensions.asd
14:44:18
shka
if you have quicklisp configured according to the manual, loading documentation-utils-extensions will automaticly load :documentation-utils
14:47:14
Satou
thanks for telling me how I should do the layout of the files beach. You mentioned something about my code being indented badly, the forms after defpackage, does the packages.lisp just contain the defpackage and the other file starting with (in-package #:cl-ipfs) contain the functions?
14:51:54
shka
oh, well i simply do (ql:quickload :documentation-utils-extensions) and quicklisp will also load everything that i depend-on (that would be documentation-utils itself)
14:52:23
Beep-Lord
Oh, I thought you meant that it would load it straight from the asd definition without having to call ql:quickload.
14:53:15
shka
well, i think it is possible somehow to do so by setting right paths and using require instead
15:01:11
oni-on-ion
https://github.com/slyrus/opticl -- whoa, surprised at the timing of the benchmark there. for somie reason i had this subconscious idea that inner loops are bulky or slow for CL. but this seems just like C
15:01:15
Satou
It is still hard for me to understand how to do that. I've created an the files as pointed by beach, but I have a hard time of using them tho
15:02:25
oni-on-ion
loke: why would there be a monster in the dark ? the subconscious is ignorant exactly because of the lack of logical reasoning and quantized details =)
15:03:51
schweers
Satou: it might be a little advanced for you, but might also be exactly what you need: there is a project called "quickproject", which sets up a skeleton. I use it every time I create a new system, as I can’t be bothered to create all those files manually.
15:03:51
oni-on-ion
i had this ancient wierd unfounded idea that lisp is generally "on top" of C. im just breaking old [thinking] habits =)
15:04:12
loke
oni-on-ion: There are several reasons one might have that impression. The two main ones would be 1) Belief that Lisp is interpreted and 2) That dynamic typing makes it slow
15:04:37
loke
2) is actually valid, but Common Lisp allows for statically declared types, which is how you get it to get close to C speed (or even faster)
15:04:43
Satou
I'm going to take a look schweers, what I haven't figured out is how to actually "run" the project
15:04:51
beach
Satou: You enter Emacs and SLIME and then you say (asdf:load-system #:name-of-my-system).
15:05:55
beach
Satou: You have to make sure ASDF can find your system definition. I am not going to say what I do because most people use the local-projects directory of Quicklisp I think.
15:06:08
oni-on-ion
i also understand that Opticl was a second run at an image library, the first being ch-image, which used full on CLOS and the CLEM matrix processing lib. Opticl is optimized for arrays specialised on types (yay)
15:06:10
schweers
Satou: the gist is: create a system by invoking quickproject from a running lisp, edit the files and load it with either ql:quickload or asdf:load-system. In either case, watch where you put your code. You can configure asdf (and thus quicklisp), but the easiest route is to just put your code under ~/common-lisp
15:07:14
oni-on-ion
loke: it was built up from several years of urban myths while i grew up on C, theres no real architecture left but ruins of the ancient city that fall away as i learn reality more actually [of lisp and of compiler optimization]
15:07:55
oni-on-ion
loke: and yea about types =) does CLOS have to be avoided to get the max optimizations here, though i wonder?
15:08:15
loke
It's very interesting to compile with different optimisation levels and type declarations to see how the generated assembly changes
15:08:35
schweers
oni-on-ion: I think o, but only do it if you can prove that you really need this kind of performance.
15:09:07
oni-on-ion
schweers: i see. wondering why the Opticl author decided against using CLOS for that time around, and "non-generic" functions
15:09:20
schweers
oni-on-ion: or as a learning excercise. But beware that the performance differences vary from implementation to implementation (for obvious reasons)
15:09:35
loke
oni-on-ion: I mean, sure, in theory you can build a generic function call that is as fast as native, but I doubt it's actually been done. In practice, however, the difference is minimal, since you don't usually have generic calls in the deepest highly-optimised loops.
15:10:20
oni-on-ion
schweers: until sbcl is not the main choice for all the reasons why it currently is
15:10:43
loke
oni-on-ion: In my red-black-tree implementation, the nodes are actually CLOS instances, and generic accessor functions are used to read/write to its members. It's pretty damn fast, but as a test I changed it all to structs (which are direct-call) and the speed difference was barely noticeable (a couple of %)
15:10:57
beach
oni-on-ion: That's a bit unfortunate, since avoiding CLOS often makes your code less modular. And SBCL's CLOS implementation is based on code that was written before the processors looked the way they do now.
15:11:18
oni-on-ion
loke: ah, okay thats cool then, thats enough for me not to worry about the difference =)
15:12:37
beach
But I designed a better generic dispatch algorithm that SICL is using and also Clasp now.
15:13:09
schweers
I make heavy use of structs instead of “regular” CLOS classes (beach: can you help me out on proper terminology?) in my main project, because I need a lot of speed (it runs for at least 48h on modern hardware). I’m seriously considering changing to CLOS, as I don’t think the performance difference is worth the hassle.
15:14:30
beach
The sad thing would be if modern code were written with old implementation techniques in mind, and that when current implementations improve, that modern code would be sub-optimal, and just obsolete instead.
15:16:34
beach
schweers: Er, so what performance gain do you think you will get from structs if you are using generic functions?
15:17:19
schweers
beach: I only use generic function on structs for a few cases. But I see your point. This is one of the reasons I’m thinking about using standard classes instead
15:18:34
loke
beach: Yes. But in practice the difference is so small I've never seen the need for it.
15:21:13
beach
schweers: As you might have seen before in my musings, the argument (similar to yours) "we need all the speed we can get", really translates to "we are willing to spend any amount of additional effort to produce and maintain this thing, even if the speed improvement is infinitesimal". Still I hear it over and over again in industry.
15:22:04
schweers
well, I don’t need /all/ the speed I can get. But yes, I see the fallacy of this reasoning in other people, but seem to have fallen victim of it myself.
15:24:00
oni-on-ion
its the caffeine junkies, honestly i think; the more caff i got in veins, the faster i want things to go
15:25:10
beach
schweers: Oh, and by the way, if you do attempt it, I am very interested in the outcome.
15:25:39
schweers
I guess it really would be best to attempt to carefully measure the runtime before and after the change
15:26:30
schweers
Ah, I remember what one of my reasons was: as far as I know sbcl does not use the types given in the slots of a standard-class, but does so in structs.
15:27:52
schweers
what exactly do you mean? what does sbcl do with the slot types when debug is 3? check on every access (write?), whether the type still holds?
15:29:13
beach
I almost never need all the speed that I could get, so I run everything with (DEBUG 3) (SPEED 0) (SAFETY 3).
15:31:02
dim
data structures come first, but well you need to have an idea of the algorithm you want to implement I guess
15:32:52
beach
Occasionally, for benchmarking code related to performance claims in a paper, I use local declarations that override this default.
15:36:33
beach
Today I have been working on specifying precise stack traversal for the SICL GC. I think I need three tables for each possible frame: One table indicating what stack locations contain local variables with Common Lisp objects. One table indicating what callee-saves registers contain variables with Common Lisp objects. And one table mapping callee-saves register so stack locations in which caller data was saved.
15:36:57
oni-on-ion
hmm "Bear in mind, though, you may get some nasty surprises by meddling with global defaults. Just for example, with those development settings, libraries that make use of tail recursion may not work properly."
15:37:37
beach
oni-on-ion: You mean libraries that count on implementation-specific handling of tail recursion?
15:38:49
beach
So, for the GC, I need to traverse the stack with a table holding frame-related values of callee-saves registers, swapping them with real stack locations as I go down the stack and swapping back when I back up the stack.
15:39:20
oni-on-ion
beach: sry not sure, its from here: https://www.reddit.com/r/lisp/comments/39i6lx/is_there_a_way_to_have_a_global_declaim/ -- i might just put :optimize in defsystem for my own stuff
15:39:56
beach
oni-on-ion: Common Lisp does not require implementations to optimize tail recursion, so a library that relies on that is not portable.
15:40:54
oni-on-ion
beach: ah makes sense, i was wondering, the guy is just extra-defensive. i won't worry.
15:42:42
beach
I have no opinion. Like I said, the things I do run fine with my default settings, except for the occasional local declaration. I have no desire to make my "production" code more optimized and less safe.
16:14:06
didi
Tell me if this is reasonable: I have a macro like `dolist', that iterates over a data structure, offering an element at each loop pass. To avoid allocating a new element for every loop pass, I'm thinking of allocating only one element and filling it with data at the beginning of the loop. This means that any program using this macro can't just take the element and run with it. Is this OK?
16:15:19
beach
didi: I don't understand. Are you elements just Common Lisp objects or are they structured in some way?
16:17:30
didi
beach: They are structured in a particular way. I interact with this data structure using an `element', but there is not `element' inside of it. When I add and `element' to it, it is broken down inside it. When I retrieve and `element' from it, it is constructed.
16:21:18
didi
beach: Sure. I have a big graph. This graph has something called a CONTACT. Whenever I want to iterate over all the contacts of this graph, I don't want to alloc each and every contact. Sometimes I just want to know if the contact I have in hand is inside this big graph.
16:22:57
beach
didi: So are there contacts associated with the nodes of the graph scattered around the graph already, and you want to search for a particular one?
16:24:05
didi
beach: Because there isn't an object contact inside it. When I ask for the contacts, it's produced using the relationships of the graph.
16:24:59
beach
Oh, so what I said was false. There are not already contacts associated with nodes in the graph. They are somehow generated during traversal?
16:26:10
didi
beach: Oh, yes. But they are local, so there's no need for a search. They are almost like labels. So a contact is a triple (vertex1, vertex2, label).
16:26:35
didi
But there is not triple (vertex1, vertex2, label) inside the graph. I have to produce it.
16:27:31
flip214
as long as it's documented that this MUST not be used outside (or in different threads!), you should be okay.
16:28:16
didi
beach: The graph is a hash table. Each hash key is a vertex, and each hash value is an associate list, where the assoc key is another vertex and the assoc value the label.
16:28:34
flip214
how about a local function that checks whether the current "element" is equal to some other one instead?
16:29:09
flip214
didi: so you have the vertexes stored twice, as V1 => V2 => label and V2 => V1 => label?