freenode/#lisp - IRC Chatlog
Search
19:11:30
francogrex
(setf (test-age *test-inst*) "aavc") is acceptable and make-array gives elements 0 ?
19:12:30
shka_
dlowe: that misses the point, i wanted to write library that integrates nicely with the rest of the world
19:12:57
mfiano
type declarations in Common Lisp are not enforced...they are merely a suggestion to the compiler.
19:13:46
dlowe
shka_: name it empty-hash-table-p or send a change to alexandria to have it changed to a method. Or send a change to alexandria to add hash table support.
19:15:30
mfiano
You would have to loop over the array. It is unclear exactly what you expect that code to do though.
19:16:53
_death
shka: it's unlikely to be incorporated.. alexandria is meant to be conservative, and I never saw an emptyp function that cares about hash-tables
19:17:16
_death
shka: nor do I remember the last time I needed to know if a hash-table is empty or not..
19:19:56
mfiano
common lisp has hash-table-count too i believe, but i don't think i've used this more than a handful in a decade of use
19:23:10
francogrex
let's try this for illustration: (let ((array (make-array 3 :element-type 'testclass))) (setf (aref array 0) *TEST-INST*))
19:23:14
shka_
in fact i would say that majority of languages actually have some sort of check if this thing is empty function
19:26:46
Fare
beach: are you here? vyzo & I would like to add features to Gerbil's object system, hopefully getting it on par with CLOS (though maybe with C3 linearization by default).
19:31:32
shka_
interface passing style is very useful when implementing data structures (very nice way to separate abstract and concrete data types) but I consider it to be cumbersome for library user
19:32:44
shka_
so although i am doing lil-like stuff under the hood, actual API is rather conventional object oriented code
19:35:36
shka_
Fare: on the other hand, i am really glad that I read your blog post describing lil, it was deeply enlightening
19:37:20
Fare
so you can *define* your library using the full power of interface-passing style, yet expose a monomorphic and/or OO interface to your users.
19:38:37
Fare
this can be useful when bootstrapping more elaborate data structures from simpler ones
19:39:11
emaczen
I'm looping, creating arrays of size 1024 and then writing these arrays to a file with #'map and #'write-char. Most of the time my file sizes are multiples of 1024 -- why would a few files not be multiples of 1024?
19:40:31
emaczen
Fare: How do I ensure UTF-8 -- I was thinking it could be a potential character-encoding issue?
19:41:28
Fare
emaczen, I don't know what you're trying to do, but uiop and asdf-encodings give you portable ways to deal with file encodings
19:41:50
shka_
needless to say, I understand motivation behind lil design after fighting similar problems
19:42:36
Fare
the next step after lil would be a linear lisp, in which all the data structure styles would be actually isomorphic at the language level.
19:43:30
Fare
shka: you should see the amazing things that ekmett does with type classes. You could do the same with lil.
20:02:52
francogrex
Bike: even with SBCL 1.3.21 i still get the style warn error :( but also maybe my build was not great: http://paste.lisp.org/display/356473
20:04:26
shka_
my implementation is a little bit niche because it allows for transactional style insert, and therefore lazy implementation can minimize consing due to copy-on write
20:05:36
Fare
not sure what exactly you mean, but yes, that's what tries are vs AVL, they have more "canonical" forms so allow for more sharing.
20:14:33
shka_
Fare: anyway, whole trick with HAMT is to store fixed (32 for instance) number of children in each node, each representing part of the hash (5 bits in the example), then adding 32 bit mask with 1 bits on positions that actually hold children
20:15:31
shka_
this way you can use combination of logcount and ldb to map hash onto into positions in vector
20:16:29
shka_
it is pretty nice because it is simple, hash can be as long as you want, it does not take whole lot of space, does not need rehashing, can be made unmutable and stuff
20:21:38
jasom
shka_: that implementation does use the lowest-order bit of the pointer for tagging, but is otherwise pretty straightforward
20:27:27
jasom
shka_: I did an implementation way back; ~2x slower than sbcl's eql hash tables for integers and ~3x for #'equal hash-tables for strings
20:31:01
jasom
ugh, 50x slower on ccl versus ccl builtin. Probably because of all the bitwise operations
20:33:46
jasom
ah ,strings are only 4x sloer than hash-tables it's purely fixnums that my critbit tree loses so badly on
20:36:53
jasom
oops, I'm actually more than 2x slower; I didn't run the benchmark code by itself for subtraction
20:37:03
jasom
shka_: https://gist.github.com/anonymous/ebcea5207209e1ef3678d7a3ef279ad0 for when you are interested
20:41:13
dim
Xach: what's the deal with rename-file? I usually use (uiop:make-pathname* :name "bar" :type nil :defaults foo), is that possible for you?
20:41:56
shka_
because of cl-ds:position-modification insanity popped up, and this REALLY need explanation
20:42:12
Xach
dim: the deal is that i don't think there is a way to make a pathname target that does not take the pathname-type of its source on clisp.
20:42:42
Xach
dim: on other implementations, it is done with :unspecific, meaning "no type and don't merge into it", on some implementations.
20:47:15
Xach
dim: CLISP has many other behaviors that are permitted but annoying. (In different, more annoying ways than, say, SBCL)
20:50:36
Xach
dim: Oh, trying to make a ported function that can rename "foo.txt" to "bar". That meant testing, and when I got to CLISP, this came up.
20:51:28
pjb
It is an error to specify a filename containing a wild component, for filespec to contain a nil component where the file system does not permit a nil component, or for the result of defaulting missing components of new-name from filespec to contain a nil component where the file system does not permit a nil component.
20:51:30
Xach
I never knew that :unspecific was not broadly supported, so it made me wonder if there was an alternative on CLISP.
20:51:40
dim
ACTION .oO(who bets pjb has an AGPL or GPLv3 lib with a portable rename-file that handle that case even in CLISP)
20:52:09
pjb
You'd lose. For pathnames I tried to make implementation work the same on the same platform.
20:52:51
Xach
It's also become a little academic - I'm not looking for "how to do this on clisp by any means necessary" but "am i missing something in clisp that would make rename-file work the way i wish"
20:55:52
jasom
minion: memo for shka: an interesting data-structure (though not necessarily of practical use over 2,4 or red-black trees) is discussed here: http://user.it.uu.se/~arnea/abs/gb.html
20:57:47
pjb
Bike: to understand that you have to understand that clisp provides a uniform API on all its target systems, which include(s|ed) MS-DOS, MS-Windows, Amiga, etc, in addition to unix system. On MS-DOS all pathnames have a type!
20:59:12
pjb
But again, I see no real point in patching pathnames or file system primitives, until we agree on a way to deal with physical pathnames in a common way on the same target platforms.
21:00:08
emaczen
how do I "set" the file encoding? I'm writing 1024 byte blocks to a file and after each disk write I have ensured that the file-length is a multiple of 1024. I guess this means that linux has added some extra bytes to my file?
21:01:04
shrdlu68
ACTION Hmm, so setting a terminal in "raw' mode is something mediated by the OS, a syscall. I was hoping it was something that could be done through ANSI ecsape codes.
21:01:06
jasom
on a related node, is there a trivial-external-formats (or some such) for generating portable code that uses :external-format?
21:02:05
dim
jasom: have a look at https://github.com/dimitri/pgloader/blob/master/src/utils/charsets.lisp for some fun and an elaborated “I don't think so” answer
21:02:06
pjb
shrdlu68: or at least a terminal emulator. Eg. xterm can switch to tek terminals that are binary.
21:03:01
pjb
or com.informatimago.clext.character-sets and com.informatimago.common-lisp.cesarum.character-sets for a "portable" way.
21:05:47
shrdlu68
I was trying to do this without having to rely on curses, and using only lisp. Final barrier is that I can't get the terminal to switch modes, such as disabling local echo.
21:06:26
pjb
Well you can always re-implement curses in CL: just go parse and read terminfo or termcap, depending on what's available on your system…
21:06:56
pjb
Then of course, *terminal-io* is a character stream, so you'll need an implementation specific to open a binary stream on the same file descriptors…
21:07:59
dim
I guess I'll find a way to do graphics in CL, meanwhile we're doing https://docs.racket-lang.org/quick/ and it's pretty nice
21:44:35
Fare
ACTION had to write uiop and discover all the pathname incompatibilities between 16 different CL implementations, the hard way
21:47:05
Fare
props go to janderson, though (a hacker I both admire and loathe), for writing the first test suite for asdf pathnames
22:17:33
Fare
dim: although everyone at work cheered when the last line of his code was expunged from the codebase (except for his open source libraries, that we kept using)
22:18:31
Fare
what I mean is that he's probably a more intelligent and better hacker than all of us were, in many ways, yet that his ability to deal with complexity is not tampered by an equivalent urge to eliminate the complexity.
22:19:00
Fare
which means that when there's a bug (or missing feature) in his code and that someone else has to change it...
22:20:39
dim
PostgreSQL mainly, but of course the helper programs and scripts I had to write to support the project are mainly done in Lisp, tho today I wrote some Go, and there's Python code included in the book too
22:22:46
Fare
I'm told Postgres used to (1) be written in Lisp, and (2) have a better designed query language than SQL (that's a very low low bar).
22:24:52
dim
1 is wrong, PostgreSQL implementation for SQL queries is basically organized in a. parser b. planner c. optimizer and d. executor, and it used to be that the optimizer would be partly in lisp
22:25:21
dim
all that's left from that area can ben seen in https://github.com/postgres/postgres/blob/master/src/include/nodes/pg_list.h
22:26:53
dim
if I had to bet I'd say what you call SQL is parts of SQL 89 with sprinkles of SQL 92, where the current standard is SQL 2016
4:13:46
minion
shka_, memo from jasom: an interesting data-structure (though not necessarily of practical use over 2,4 or red-black trees) is discussed here: http://user.it.uu.se/~arnea/abs/gb.html
4:58:46
beach
jmercouris: There are tons of small problems with the code. Do you want remarks about those as well? I find it extremely hard to understand the meaning of some code when I am distracted by the superficial problems.
4:59:20
beach
jmercouris: Also, perhaps you should expose your code here so that other people have a chance to give you feedback as well.
5:02:36
beach
jmercouris: And, do you have any specification for what you are doing? You haven't even told me what the software is supposed to do.
5:13:56
jmercouris
beach: The specification is kind of outlined here: https://github.com/nEXT-Browser/nEXT/tree/master/next#release-timeline
5:14:27
jmercouris
Also, it's less of a specification, and more just like a list of features, the quick jist is an "emacs" browser
5:15:08
jmercouris
beach: Yeah, I'm sure I saw it, but I didn't quite apply it so well, is there an automatic way of linting or do I just have to know them all?
5:16:22
jmercouris
also, are you referring to the following style guide?: https://www.cs.umd.edu/~nau/cmsc421/norvig-lisp-style.pdf
5:16:53
jmercouris
beach: Sorry for my omission, I had just assumed you already knew for some reason :\
5:19:14
jmercouris
Right, I kind of see the order of specificity here, I know I violate the if one frequently
5:21:51
beach
The compiler accepts any grammatical expression. The reader of your code only wants idiomatic expressions, and those are a small subset of the grammatical ones.
5:22:21
beach
I write (unless (null children) ...) because then (null children) checks whether the list is the empty list, and unless is given a Boolean value.
5:23:26
Zhivago
Of course, it might be better add empty-list-p to make sure that it's clear that you expect a list rather than a symbol. :)
5:24:33
jmercouris
beach: Do you think I should copy the email body to a pastebin as well so that others may read it?
5:24:57
jmercouris
Zhivago: would you also be interested in reading the email/critiquing the codebase?
5:26:45
beach
jmercouris: Many of us #lisp participants dislike the naming convention that consists of prefixing the slot accessor with the name of the class. It looks very strange when there are deeply nested subclasses, like in McCLIM (SHEET-CHILDREN MY-PANE).
5:28:01
jmercouris
beach: I just kind of copied it from the struct functionality that was already there when I converted to CLOS, how would you suggest I name things instead?
5:28:37
jmercouris
beach: ok, will do, and there should be no collisions right because these are methods, yeah?
5:28:55
Zhivago
There may be collisions, since methods are part of generic-functions which should have coherent semantics.
5:29:46
jmercouris
Zhivago: are you saying if I have two slots accessors with the same name in two different classes there will be a collision unless they are part of a different package?
5:29:53
Zhivago
That is, you're not calling or naming method -- you're calling and naming generic-functions.
5:30:07
beach
jmercouris: Your LOOPs are badly indented and formatted. Use SLIME-INDENTATION and put the LOOP keywords first on a line.
5:30:49
Zhivago
I'd rephrase that as, "If I have one generic function that implements slot accessors for two different classes".
5:32:48
beach
jmercouris: You certainly don't want a return-from as the last form of a function. The last form is returned by default.
5:33:15
Zhivago
Personally I suggest that slot accessors should generally not be exposed in any case.
5:34:07
Zhivago
Well, you need something to access the slots, but the slots are really an implementation detail -- having things outside the class use them is usually not a great idea.
5:34:37
jmercouris
beach: that makes sense, I'll try to remove the return-froms where possible, I know there are a couple of exceptions to this where I must keep it for behavior due to QT
5:34:47
Zhivago
If you expose the slots then the slot semantics become part of your object semantics.
5:34:53
beach
jmercouris: The widely agreed-upon convention for special variables is to give them *earmuffs*.
5:36:44
Zhivago
jmercouris: You might find that (with-active-buffer ...) has nicer semantics than (set-active-buffer ...)
5:37:26
jmercouris
beach: ah, this is true, yes, but I wanted to make it like emacs, maybe I'll make it special, not sure
5:37:55
jmercouris
Zhivago: are you suggesting just renaming the function, or making like a wrapper function?
5:38:27
Zhivago
I was suggesting that you expose a (with- ...) which sets and restores, rather than exposing (set- ...) but it's just a suggestion.
5:38:49
jmercouris
Zhivago: that's a really good idea, I gotcha, I will definitely do that, it's like a python context manager
5:40:15
jmercouris
Zhivago: are you referring to: "If a defvar or defparameter form appears as a top level form, the compiler must recognize that the name has been proclaimed special."?
6:00:15
jmercouris
Well, anyways, thank you both for the valuable feedback, I'll try to make some of these syntactical/idiomatic changes and hopefully write cleaner code
6:00:38
jmercouris
The one question I still have though is, is my approach with the *active-buffer* and the regular functions bad? should I use methods instead?
6:06:47
Zhivago
I think that the idea of having an active buffer in the dynamic context is quite lispy.
6:07:30
beach
jmercouris: I will let you know when the code is in a good-enough shape that I can read it for what it means and not be distracted by superficial stuff.
6:10:23
beach
jmercouris: In stead of doing (if bla (funcall fun <stuff1>) (funcall fun <stuff2>)) it is more Lispy to do (funcall fun (if bla <stuff1> <stuff2>))
6:11:39
beach
jmercouris: I would definitely create a MINIBUFFER abstraction instead of having all those special variables.
6:17:15
jmercouris
beach: how would I make it sort of globally accessible? what's a good singleton pattern?
6:18:39
beach
You store an instance in a single special variable rather than having a special variable for each feature.
6:25:57
pjb
Well, if you want to test for empty lists, in general you should rather use endp instead of null.
6:26:51
pjb
Zhivago: NULL tests for the NIL value, not the NIL type. There is no object in the NIL type! (constantly nil) would be the test for the NIL type!
6:55:00
lexicall
Hi, a package system related problem here. I defined macro AIF in package A and used that macro in package B (:shadowing-import-from #:A #:AIF). i wrote code (aif true it false), but it expands to (LET ((A::IT 1)) (IF A::IT IT IT)), so the compiler explains "Error: The variable IT is unbound." the latter IT does not refer to the former one, which is in package A.
7:03:25
|3b|
or arrange for the AIF to do ugly tricks with symbol generation and hope they don't bite you later
7:07:31
beach
lexicall: What |3b| says. The package of a symbol is determined when the symbol is read, so the symbols IT in the AIF macro is interned in the package named A.