freenode/lisp - IRC Chatlog
Search
11:36:26
elderK
Say, I'm separating things into their own packages, for namespacing reasons. But then, I have a "unification" package, which brings in and exports just the stuff I want people to use?
11:41:05
beach
elderK: You have one package that contains symbols that you want to be visible by client code. It contains only those symbols. No code is written with an IN-PACKAGE of that package.
11:42:27
beach
elderK: Then you have several "implementation packages". You may have one or more files that start with (IN-PACKAGE ...) of one of those implementation packages.
11:42:52
beach
In such a file, you do (defun main-package:function1 ...) (defclass main-package:class1 ..) etc.
11:44:28
beach
elderK: It works, because packages contain only symbols. They are not modules so they don't contain code or definitions.
11:46:49
elderK
beach: I see. So, I have one "proper package", and a bunch of internal packages. Those internal packages do not need to have a defpackage form?
11:47:40
beach
And you can have as many as you like. Client code will only see symbols in the main package.
11:48:31
beach
I often put each "implementation module" in its own directory. Then I have a separate package.lisp file for each such module, in its directory.
11:49:00
beach
One of my "modules" typical consists of a directory, a package.lisp file, and an ASDF system definition.
11:49:08
elderK
Okay, so, I have my various packages. I have one "main" package which is to be used by people. All my internal stuff is in the internal packages, and for the things in those "internal" packages, where they define something that is meant to be in the public interface, they just define it straight into that pacage?
11:49:18
beach
That way, I can have alternative implementation for the same functionality if that's what I want.
11:50:13
elderK
This might be overkill for what I'm doing. I just want to make sure the names I've used for helpers, for one set of macros, doesn't conflict with the helpers for another macro.
11:50:45
beach
More precisely, code in one of the implementation modules uses the main package as a package prefix directly for defining functionality that is to be seen by client code.
11:51:25
elderK
So, why is this method preferred over the one where you import and rexport from the internal packags?
11:52:40
beach
The structure is also simpler than if you have to import and re-export every symbol explicitly.
11:53:17
beach
And client code can be sure that the main package contains only visible symbols, in case it wants to iterate over all symbols avaliable to it.
11:53:30
elderK
So, what if one of my implementation packages wants to add some new symbols to the main package, but also use some symbols from the main package?
11:54:39
beach
And I just explained how implementation modules use the symbols from the main package, namely by using a package prefix.
11:55:08
beach
That way, it is much more obvious to someone reading the code for the implementation module what symbols come from the main package.
11:55:35
beach
Plus, you can use symbols with the same name in the implementation package as the corresponding symbol in the main package without any clashes.
11:56:14
ogamita
The current style of development, where the code is stored in files that are loaded and compiled separately by a system definition system (asdf), asks for a more static declaration of some elements such as the packages.
11:57:15
ogamita
Note that this prevents circular dependencies between packages (this is good software engineering practice!). But lisp allows circular dependencies between packages, established at run-time. You can find them in legacy code, but don't do it yourself.
12:15:29
jmercouris
elderK: well, in this case it is a function that given a string, and a list of strings, will return a list of strings that fuzzily match
12:16:37
jmercouris
in other words, there is not a strict convention as there is with something like predicates
12:18:34
jmercouris
I think I might do something like that though, with -fn at the end suffixed, I like it
12:22:16
ogamita
I would use fuzzy-matcher or just fuzzy-match. I'd decide on the name depending on usage. (funcall (fuzzy-match foo) bar)
12:22:38
elderK
I'm trying to apply what beach explained earlier. But now, because of specifying the package name, lines are way longer.
12:24:14
elderK
What happens if a package A says it exports symbols S1, S2. And package B uses package A, and contains a definition for those S1, S2. Do those definitions wind up being the definitions for A's S1, S2?
12:25:02
elderK
Or do those definitions for S1, S2 in B shadow those from A? (Those symbols have no definition in A, though.)
12:26:21
Bike
if you have like, a:s1, and *package* is B, and B uses A, and you read "s1" by itself, that will be a:s1
12:26:25
elderK
:( Sorry, I'm using bad terminology. The packages contain the symbols, right? That's all. But somehow, you associate a binding for that symbol, no?
12:27:53
elderK
Okay, so if I have a package B that uses package A, which contains the symbol S1, and I (defun S1 ...) in package B, is that function bound to the symbol S1. So, if someone later uses Package A, and calls S1, it uses the function that was defined with that name from B?
12:28:45
Bike
Try it: (defpackage #:foo (:export #:s1)) (defpackage #:bar (:use #:foo)) (let ((*package* (find-package "BAR"))) (read-from-string "S1"))
12:30:37
Bike
this happens way before anything like defun is compiled or evaluated. it's just how the code is parsed.
12:31:07
ogamita
(defpackage "INTERFACE" (:use) (:export "S1" "S2")) (defpackage "IMPLEMENTATION" (:use "CL" "INTERFACE")) (in-package "IMPLEMENTATION") (defun s1 () 1) (defun s2 () 2) (defpackage "CLIENT" (:use "INTERFACE")) (in-package "CLIENT") (cl:list (s1) (s2)) #| --> (1 2) |#
12:32:50
splittist
elderK: some people like this explanation (warning: pdf) http://www.flownet.com/gat/packages.pdf
12:35:18
ogamita
another explanation is an implementation of the package system: https://github.com/informatimago/lisp/tree/master/common-lisp/lisp-reader
12:37:09
ogamita
elderK: otherwise, the trick is to read the operators. defpackage defpackage in-package defun defun defpackage in-package.
12:50:14
p_l
I think stuff that has literal CL:ASSERT isn't compiled out, but implicit asserts (like type declarations) can be optimized out
12:53:17
jcowan
elderK: It could all be much worse: you could be trying to wrap your head around the R6RS notion of explicit phasing, with its doubly infinite tower of (in effect) eval-when situations: normal code, macros, functions used by macros, macros in the last, functions used by the last, and so on forever. Then there are negative phases, which I can only understand for brief periods before forgetting again
12:53:52
jcowan
fortunately, only one Scheme is left standing that implements this, and it will be phased out before 1.0
12:54:42
ogamita
elderK: you could use a feature: #-with-heavy-assert (assert (2-hours-compute-predicate-p foo))
12:55:20
ogamita
elderK: so you cah (push :without-heavy-assert *features*) and reread/recompile to remove the assert.
13:30:16
jcowan
From the Vax Lisp (it's a CL) manual: "You can recover an input expression or an output value by using the following 10 unique variables: / // /// * ** *** + ++ +++". Something a bit wrong here?
13:39:48
jcowan
I don't think base 8 made it off the PDP-10 except in the rudimentary form of *input-base*.
14:18:16
Xach
sometimes i have a function that is really just a thin wrapper over gethash, for example, but i'd like to hide the extra return value
14:19:08
elderK
Well, if my function is meant to return a single value, well. I'd like that to be the case :)
14:44:27
dim
The standard has it that “values is the standard idiom for indicating that only one value is to be returned”
14:50:45
ggole
(values (values 1 2)) is an interesting snippet - the same operator doing quite different jobs
14:54:22
Xach
Inline: forms don't expand into multiple forms, but they may evaluate to multiple values.
15:23:49
jackdaniel
this is fun to read: https://bugs.launchpad.net/calibre/+bug/1714107 (some folks trying to convince calibre maintainers to migrate from python2 to python3, because the former is "retiring") [sorry for the offtopic, otoh it proves, that having standard is a nice quality]
15:29:27
Xach
I think there's sometimes a simplistic view of what motivates other people to change their code for you
15:30:08
beach
This is precisely what I am talking about when I give talks to industry, urging them to use standardized languages.
15:30:19
Xach
"change this to make it conform to the standard" does not always motivate someone to make a change.
15:31:02
Xach
common lisp adherence to standards (in a thorough way) has not always been very good, and it saw a surge of improvement over the last 10 or so years
15:31:43
Xach
but if you rely on something standard, but your platform does not implement the standard, you cannot always rely on "change to fit the standard" to save you, without other agreements
15:36:11
fade
the incompatibility between python 2 -> 3 was what lead me to finally use CL in anger.
15:36:30
fade
"If it's going to be a different language anyway, I may as well use one that is both fast and stable."
15:38:07
ogamita
popularity leads to legacy, legacy leads to bit rot, bit rod leads to the dark side.
15:38:40
fade
the 2 -> 3 migration has been the biggest fuckup in a language ecosystem since I've been watching such things, a period dating back to the mid 1980's.
15:39:33
fade
I've often thought that it should result in a lot of new developers for lisp, but I haven't run into too many.
15:41:59
sjl_
Porting a large Python 2 codebase to Python 3 would be painful, but much less effort than learning CL and porting it to CL. That's one possible reason.
15:43:12
pfdietz
Xach: widespread non-compliance with the standard motivated me 15 years ago or so to write ansi-tests.
15:43:33
nixfreak
hello how can I get started to created a "HOT" folder , meaning certain files get copied to a file and a script gets executed to push those files somewhere else
15:44:02
Fade
sjl -- that's true, but once you've loaded lisp into your head, you've solved all of the problems associated with the python ecosystem permanently, if only locally.
15:45:22
sjl_
Fade: sure, but the first part of that (learning Lisp) is non-trivial, and the urge to "Fix the problem and move on with my life instead of learning new tools" is often strong.
15:45:37
Fade
lisp can open and append files, and with the right extension, open a socket and move data through it.
15:46:42
minion
nixfreak: 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).
15:46:49
fortitude
has anybody used cffi-grovel:process-grovel-file in a while? seems to be an issue with its use of uiop:ensure-pathname, but the last relevant change was from 2015
15:46:56
sjl_
I mean, I agree with you -- Python 3 and Clojure 1.3 were a big influence on me choosing a stable language like CL. But I can understand the decision to suffer through an update rather than go through a full rewrite.
17:13:45
beach
That reminds me of a student I had in the past who wrote is C code with single letter variables only. When I asked him why, he said so that the program would execute faster.
17:16:05
sjl_
uLisp is fun if you do Arduino-based stuff. I've used it for a couple things. I even hacked in floating point support, and the author eventually merged it into the main repo.
17:17:40
copec
I have a smartos box doing all the things, and I actually just want to do rpc with them
17:18:23
sjl_
The homepage says > platforms with more than 2 Kbytes of RAM arbitrary user-defined symbol names are supported.
17:19:48
copec
I want the actual control to be in a zone on the smartos box with the devices just acting as control bridges
17:23:08
didi
I can't get over the fact FORMAT doesn't have a directive to print conses. It bothers me when I want to print alists.
17:24:12
copec
although, having my kids directly program some micro controller projects with this ulisp would be fun
17:26:03
Bike
i guess you could map the alist to have actual lists beforehand, or use ~//, but it's not quite as smooth
17:26:12
anamorphic
copec: I used mqt for rpc previously with esp8266s. I would like to try it again with ulisp
17:32:59
copec
The 'protocol for updating using semantics that follow from CL would suite it wonderfully, I think.
17:43:35
copec
That thought just came to me thinking about these micro controller system images being all lisp, something something nasa doing incremental upgrades through space via lisp, and how cloud app deployment is going towards orchestration (config management) states to deploy applications
21:01:31
dim
is there a guide to port CL software to ABCL? I mean the JVM comes with many libs that you can reuse without having to load CL equivalents I'm sure (jdbc for db drivers, zip, http, s3 maybe, usocket needs a replacement, json?, uuid?, base64?)
21:24:05
jackdaniel
I think that the proper way to tackle that would be defining a protocol (so the package and exported interfaces are defined) and to provide implementation for that
21:24:56
jackdaniel
example: uffi had a specification (which had implementation called uffi), and later cffi-uffi-compat iimplemented the same protocol and ecl ffi did the same
21:25:24
jackdaniel
so they are a drop-in replacements (you may use cffi-uffi-compat instead of original uffi)
21:30:42
dim
in the case of PostgreSQL/MySQL/SQLite/MSSQL/Oracle/DB2 and other database protocols, CL typically has a separate specialized driver each time where the Java world uses JDBC, often with quality drivers that you'd want to benefit from when you're on the JVM anyway
21:31:30
dim
so even though I like your idea of protocols and their various implementations, well... it's not clear how much that'd be necessary for me here
23:02:28
v0|d
pjb: #emacs guys had no ideas, do you know a way to make (mapcar (lambda (a) (concat "x" a)) (eshell/ls)) work?
23:04:23
pjb
of course, inside eshell it prints out the list. But as a function it doesn't return anything.