freenode/lisp - IRC Chatlog
Search
18:25:59
phoe
I have a list of triples in form (X Y Z). I am inside a loop that iterates over two variables. How can I find the value of Z if there is a triple with a matching X and Y in the list?
18:27:42
Bike
(third (find-if (lambda (triple) (and (eql (first triple) x) (eql (second triple) y))) list-of-triples))?
18:38:38
dlowe
(find (list x y) list-of-triples :test #'equal :key (lambda (x) (list (first x) (second x))))
19:17:04
pjb
grewal: imagine a shell script, but it uses non-standard applications and shell libraries!
19:17:57
pjb
grewal: definitely. You make a single-file executable. Or you provide a tarball to install in /opt/apps/$yourscript/ with a script to install in /usr/local/bin/$yourscript
19:19:29
pjb
grewal: there's cl-launch, but it doesn't work like I want, so in the end, now I build all my CL scripts (that used to hav #!/usr/local/bin/clisp …), in a single executable image called commands, and a bunch of symlinks into it.
19:22:16
pjb
grewal: oh yeah, the big problem with cl-launch, is that it compiles the lisp script. This means that you cannot write scripts that modify the environment for the rest of the script. This is something that is routinely done in scripts (bash, ruby, python, perl, lisp, whatever).
19:22:48
pjb
Once cl-launch compiles, we're not in the script world anymore, so you can as well compile and save an executable image.
19:24:12
grewal
I guess the biggest hangup is (potentially) having multiple copies of the same libraries
19:24:17
pjb
your scripts can be used by any users on any system. You cannot override the user's ~/quicklisp, so you have to setup a quicklisp elsewhere. (/usr/local/share/myscript/quicklisp for example). This is not a script, when you have external file dependencies.
19:24:32
dtw
grewal: You can distribute code, of course. Write a Makefile that installs Quicklisp and eventually compiles executable. I do that: https://github.com/tlikonen/tagdb
19:24:52
pjb
grewal: if the user can make a (quick-update) and break your script because it fetches a new version of a library, this is BAD!
19:25:58
grewal
pjb: I meant copies. If two different lisp images have cl-ppcre baked in, then you have 2 copies of the same library on your system
19:26:58
grewal
Obviously, if you need to pin to a particular version, then you have no choice. But most apis are stable
19:27:54
jasom
grewal: I would suggest just using ASDF and the consumer can quickload things if needed
19:28:37
pjb
grewal: again, it's not copies, it's two versions that happend to be the same version, but that at any time, can change in one, and not in the other.
19:28:59
pjb
grewal: or you must be prepared to recompile all your lisp software as soon as you do a (quick-update) (every month!)
19:48:21
_death
pjb: typo @ https://github.com/informatimago/commands/blob/master/generate-commands.lisp#L65
21:03:26
dale
I'm trying to do something like (let ((n 42)) (loop for n = n then n+1 until (>= n 50))) but n is nil on the first trip through the loop. Is there a good (or "remotely sane, relative to loop") way to have loop initialize its n from the surrounding n binding?
21:09:30
dale
verisimilitude: Sorry, my simplified example was obviously oversimplified. The actual code is a bit more complicated: http://ix.io/1Ezd/lisp
21:10:30
dale
verisimilitude: If I use WITH, how do I reassign n on each iteration after the first? Just slam in a DO (SETQ ...)?
21:11:54
verisimilitude
I agree that a simple renaming is likely easiest, but I'm wondering why you need N = N to start with.
21:12:45
dale
verisimilitude: I could rewrite it with a single FOR clause a la: for marker = (nav-stack-go-newer nav-stack-global-stack n) then (nav-stack-go-newer nav-stack-global-stack direction)
21:13:05
makomo
you'd like to start off with the outer value but then do something else on all the other iterations
21:13:58
makomo
dale: i've had a construct like that as well in some code, but the duplication annoys me
21:14:32
dale
I was surprised that "FOR n = n" seems to be like (let (n) (setq n n) ...) rather than (let ((n n)) ...).
21:14:56
dale
Well, I'm mostly thankful not to have been missing something obvious about loop. Thanks folks.
21:20:20
verisimilitude
The FOR = clause does set to NIL, yes. You should simply change the symbol you're using.
21:25:55
verisimilitude
I swear this is one of those pitfalls of LOOP that I had in mind at one point and had simply forgotten by now.
21:26:41
dale
verisimilitude: See, I was trying to very carefully avoid disclosing that I'm actually using cl-loop in Elisp.
21:27:00
dale
verisimilitude: Writing a little code to help me navigating back and forth through source files in Emacs.
21:27:55
dale
But before I asked here I did test what I believed to be equivalent code in SBCL first. :)
22:06:15
comborico1611
I am trying to STEP through a program. But the inner workings of the REPL continue to be included in STEP output. The last thing I've done is called STEP from within the compiled file. I've tried with both SBCL and Allegro. Any ideas?
22:08:57
moldybits
btw, maybe you could make a minimal testcase showing what you get vs what you'd like
22:16:43
pjb
comborico1611: or you may try cl-stepper: https://groups.google.com/d/msg/comp.lang.lisp/nj3jFxcJYM0/QbzGkAbyAtMJ
0:55:44
asarch
One stupid question: I've write a paint program (cl-paint) and I would like to check at its startup if there is already a running process of itself in order to prevent another "instance" of the application. How would I do that?
0:57:01
White_Flame
but, what many programs do in that situation is write a file somewhere containing the OS process id of the running program
0:58:43
verisimilitude
The example of the process ID, as with most things in UNIX, is fragile and held together by convention rather than technical measures.
0:59:23
White_Flame
you could also hold a socket open or something, but afaik there isn't a standard mechanism
0:59:44
White_Flame
generally, it's realy annoying if you don't let a user do somethign they want to do
1:03:42
asarch
I guess I could warn to the user with a "It seems that there is an already running process of the paint program. If not, delete manually the .cl-paint-pid and then retry"
1:04:09
asarch
However, the stupid user also could delete it manually and start another process, right?
1:30:47
verisimilitude
Firefox does this and, for that reason and many others, it's one of the worst programs I regularly use.
1:33:50
pjb
You have two cases: either your program needs exclusive access to a specific resource, or it does not.
1:34:24
pjb
In the former case, you should just test for the exclusive access to the resource, but you should not forbid multiple instances.
1:34:41
verisimilitude
If it really needs exclusive access, it should use a foolproof mechanism, but that unfortunately depends on the nature of the resource, since the OS isn't going to help at all.
2:05:21
White_Flame
with firefox, it uses a bunch of profile information on the local disk, so it needs to serialize on that
4:29:58
pjb
(loop for voo in '(k1 k2 k3) collect (case voo ((k1 k2) '12) (k3 '3))) #| --> (12 12 3) |#
4:31:06
pjb
cryptopsy: actually I would advise to always wrap the keys in the case clauses in parentheses, even when there is a single one (case voo ((k1 k2) '12) ((k3) '3) ((nil) '0)) for the case where you want to test for nil. Because (case nil (nil 'nope) ((nil) 'yep)) #| --> yep |#
4:33:56
cryptopsy
can i do 'else' in a case? like, if none of the cases matched, then do that thing keyn
4:34:36
pjb
(case 3 (2 'nope) (otherwise 'yep)) #| --> yep |# (case 3 (2 'nope) (t 'yep)) #| --> yep |#
4:36:01
pjb
it's used usually in cond or the otherwise case: (let ((foo 3)) (cond ((eql foo 2) 'nope) (t 'default))) #| --> default |#
4:36:51
pjb
on the paper, 0 and 1 were used in 1959, but in the first implementation they already switched to symbols, NIL and T.
4:37:21
cryptopsy
i understand that its a binary logic, just not why it would be true rather than nil
4:37:39
pjb
That was long before otherwise was considered as a keyword. otherwise would have taken two word to store the characters, and two words to store the pointers of the list, so it would have be a little costly as a keyword…
4:37:44
cryptopsy
'otherwise' more like it would be a false, as in it is false that there was a match
4:38:15
pjb
Have a look at https://www.reddit.com/r/lisp/comments/4mp4oy/lisp_i_and_lisp_15_manuals_source_code/
4:39:22
pjb
antecedent1 -> consequent1 , antecedent2 -> consequent2 , … , true -> default-consequent
4:41:25
pjb
that's where the CAR and CDR came from, and this processor also had a XEC instruction similat to eval, to execute an instruction stored at the given address.
4:42:06
pjb
cryptopsy: you understand now why the cost of the computer was nothing: it was the cost of the electric and air conditioner installation, and electricity bill.
4:43:17
pjb
The first 7090 installation was in November 1959. In 1960, a typical system sold for $2.9 million (equivalent to $18 million in 2018) or could be rented for $63,500 a month (equivalent to $405,000 in 2016).
4:43:26
cryptopsy
there are surface grinders with 100kw motors, when the factor runs those the power bill goes up by millions of dollars for the month
4:47:05
pjb
The basic memory cycle was 2.18 μs, so basically (/ 2.18e-6) #| --> 458715.62 |# less than half a mega instructions per second at most.
4:47:57
cryptopsy
i made this program to try to count whitespace at the beginning of each line, but it doesnt give any output when running in sbcl (stuck?) https://pastebin.com/TLvrS9NH
4:50:33
pjb
defvar (and all other forms with operator having a name prefixed with "DEF") should only be used as a toplevel form.
4:51:16
pjb
The reason is because its effects cannot be known before the expression is compiled. So the indent variable in your expression cannot be the indent variable defined by defvar.
4:51:49
pjb
Also, defvar and defparameter define special variables. Since they're special you should name them with stars *indent* to show that they're special and so you're careful in their use.
4:52:09
pjb
The specialness of those variable is that all their bindings are dynamic bindings, not lexical binding.
4:52:46
pjb
You can use (count-if (lambda (ch) (find ch #(#\space #\tab))) line) to count the spaces in a line.
4:53:25
pjb
(well, technically there are a few operators that preserve the toplevelness: progn and eval-when amongst others).
4:54:33
cryptopsy
i had put the definition there so that it gets reinitialized to 0 for each line read
4:55:05
pjb
cryptopsy: also, defvar and defparameter define global variables. You should avoid global variables.
5:00:14
pjb
The advantage of using :for, is that it doesn't intern the symbolin the current package, so if you later use-package a package that exports a symbol with the same name as one loop keyword, you won't get a collision.
5:01:10
pjb
Also, the advantage is to use := instead of = := means assignment, while = means equality…
5:08:59
pjb
cryptopsy: https://pastebin.com/NBn740xp you can use position-if-not to find the first non-space character.
5:09:39
pjb
However, it the line is empty, it returns NIL, so you may want to wrap (or (position-if-not …) 0) to fallback to 0 on those lines.
5:23:06
beach
Otherwise, you force people to count parentheses, which Common Lisp programmers never do.
5:23:51
cryptopsy
that's why i put them on their own lines, so i can fold blocks and copy and paste them around
5:26:59
beach
So start by using an editor that understands Common Lisp syntax to indent your code, and remove all the whitespace before closing parentheses.
5:58:30
akater
seok: when it makes sense to process elements of a sequence in parallel, for example. E.g. if you integrate over the elements. But it's not a hard rule. Lists are often convenient.
5:58:41
beach
seok: When you want O(1) access to the elements and you don't need to change the number of elements very often
6:00:33
beach
seok: Use an array (of which a vector is a special case) when you want O(1) access to the elements and you don't need to change the number of elements very often.
6:02:46
verisimilitude
In any case, it can usually be rather easy to switch them around, without changing the code.
6:03:20
verisimilitude
VECTORs and LISTs are both considered SEQUENCEs and many functions simply work on those.
6:13:01
jackdaniel
seok: do not use lists to represent arrays, they are literally given as an example what one shouldn't do in one of Norvig's essays
6:15:44
jackdaniel
(lists are very versatile and are useful for many things, representing arrays is *not* one of them)