lmy9900 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
sz0 has joined #lisp
clintm has joined #lisp
dacoda has quit [Remote host closed the connection]
robdog_ has quit [Remote host closed the connection]
arescorpio has joined #lisp
arescorpio has quit [Max SendQ exceeded]
arescorpio has joined #lisp
emaczen has quit [Ping timeout: 268 seconds]
<pfdietz>
If you wanted to create an immutable vector, then (eval v), or perhaps (eval (list 'quote v)), would do it. Perhaps one of the few good uses of eval.
<Bike>
i think if there were actual runtime-immutable structures it would probably be better to expose a function to make em
robdog has joined #lisp
robdog has quit [Ping timeout: 268 seconds]
xristos has joined #lisp
Kaisyu has joined #lisp
themsay has quit [Ping timeout: 246 seconds]
themsay has joined #lisp
fikka has quit [Ping timeout: 244 seconds]
rumbler31 has quit [Remote host closed the connection]
Essadon has quit [Quit: Qutting]
rumbler31 has joined #lisp
<aeth>
pfdietz: You don't need to eval, though. You can also write a macro to produce essentially the same result, which would be even more preferable.
pjb has quit [Read error: Connection reset by peer]
pjb has joined #lisp
<aeth>
Bike: You'd also want to expose the subtype because you'd need type declarations to actually allow the compiler to assume that they're immutable when you use something like car or aref. (Well, you could also just directly declare them, but that solution is messier than a type one.)
robdog has joined #lisp
fikka has joined #lisp
rumbler31 has quit [Remote host closed the connection]
arescorpio has quit [Read error: No route to host]
rumbler31 has joined #lisp
nirved has quit [Killed (adams.freenode.net (Nickname regained by services))]
nirved has joined #lisp
nirved is now known as Guest57209
nirved has joined #lisp
Guest57209 has quit [Ping timeout: 252 seconds]
robdog_ has joined #lisp
marusich has quit [Quit: Leaving]
robdog has quit [Ping timeout: 252 seconds]
sindan has quit [Ping timeout: 268 seconds]
esrse has joined #lisp
sz0 has quit [Quit: Connection closed for inactivity]
lucasb has quit [Quit: Connection closed for inactivity]
beach` has joined #lisp
<fiddlerwoaroof>
jcowan: hmm, isn't there a fifth case where you want to append an element to a list in O(1) time?
<fiddlerwoaroof>
so, you store the list in question as (cons the-list (last the-list))
<jcowan>
Yes, that's a tconc structure. But it could as well be (defstruct first last)
<fiddlerwoaroof>
Sure, but the advantage of using mutable conses is you don't need a conversion to use the underlying list with the rest of CL
<fiddlerwoaroof>
you just need to make sure you update the tconc function before trying to append again
<fiddlerwoaroof>
I dunno, I appreciate the value of immutability (it makes certain things much more reliable) but I do think we don't think about the costs
beach has quit [Ping timeout: 252 seconds]
<fiddlerwoaroof>
that is, we overlook the costs
ebrasca has quit [Read error: Connection reset by peer]
ebrasca has joined #lisp
<pfdietz>
aeth: how does a macro do it? I'm thinking of the case where the vector is not known at compile time.
robdog has joined #lisp
<jcowan>
fiddlerwoaroof: No, I mean a structure just to hold the first-pair and last-pair pointers; the list itself remains just a list.
<jcowan>
Oh, I see, you mean the list has to be made of mutable pairs. So it does.
<aeth>
pfdietz: The general case, which does require everything to be known, seems to be (defmacro literal (thing) `',(eval thing))
Mr-Potter has quit [Ping timeout: 240 seconds]
makomo has quit [Ping timeout: 240 seconds]
<aeth>
I'm actually not sure anymore if there's a way around an eval somewhere.
<pfdietz>
What I was getting at was that as soon as something shows up as a literal in evaluated code, it becomes unconforming for a program to modify it. So an implementation could flag it as immutable, even if it had been created at run time, not compile time.
<pfdietz>
And even if it had been mutable before then.
<pfdietz>
Another interesting game: a way to make compile time constants behave as if they were created with hash consing (so equal constant are eql).
<pfdietz>
(hcons 'a 'b) ==> turns into a LOAD-TIME-VALUE that looks this up in a hash table.
<jcowan>
Ah, Dr. Goto's hash conses!
<jcowan>
(He used to complain cheerfully that he was always being eliminated.)
<pfdietz>
Another victim of structured programming.
<jcowan>
He died in 2005, so no, I don't think so.
slaterr has quit [Quit: quit]
<pfdietz>
Outlived Dijkstra by three years.
robwgla has joined #lisp
<jcowan>
Alas, his paper does not appear to be online.
* pfdietz
is being facetious.
<jcowan>
Knuth, author of "Structured programming with goto statements" (a great paper) has outlived both of them.
<pfdietz>
I am old enough to remember reading it when it came out.
lmy9900 has quit [Client Quit]
<pfdietz>
Hash consing is what you can use if you give up EQ on cons cells, just use EQUAL.
<pfdietz>
There's a poor man's hash consing that doesn't hash.
<pfdietz>
Instead, when you do (equal x y), if this is true and x and y are not eq, then do (setf (car x) (car y) (cdr x) (cdr y)) (say). Each comparison increases sharing.
<jcowan>
Goto's paper is from 1974 and is called "Monocopy and associative algorithms in extended Lisp". Tokyo: University of Tokyo Technical Report TR 74-03. It might be possible for someone to retrieve it given that.
pjb has quit [Read error: Connection reset by peer]
jello_pudding has quit [Ping timeout: 268 seconds]
jello_pudding has joined #lisp
jellopudding has joined #lisp
jello_pudding has quit [Remote host closed the connection]
<p_l>
beach: I think I recall reading about the idea in the past. Not sure if it wasn't mentioned in Peopleware
<beach>
Maybe so.
elderK has joined #lisp
<beach>
The basic idea from Kahneman's book is that the brain has two modules, one fast and one slow. The fast one is lousy when it comes to statistics and arithmetic, and the slow one is lazy in that it tends to believe the fast one.
emaczen has quit [Remote host closed the connection]
<p_l>
beach: it curiously connects with the AI saying of "hard things are easy, easy things are hard"
<beach>
Heh.
<beach>
If you haven't read the book, I highly recommend it.
<p_l>
Haven't yet
<beach>
It is not terribly thick. It is easy to understand, and it gets you thinking about our activity and how people around us think.
<p_l>
Will add to my list ;-)
<beach>
Put it near the top. :)
<beach>
... or the front, I guess. :)
<beach>
Seriously, it is a very important subject, and very relevant to what we do.
<beach>
On a daily basis I see the effects of the phenomena of the book here on IRC.
orivej has joined #lisp
robdog_ has joined #lisp
ebrasca has quit [Remote host closed the connection]
robdog_ has quit [Ping timeout: 268 seconds]
<elderK>
shka__: After looking into the MOP, I'm thinking of still using defstruct (or defclass) and suitable macros.
<elderK>
shka__: Although, I'm still kind of undecided. A real issue would be having defstruct-style inheritance restrictions.
<p_l>
Meanwhile I'm enjoying my just desserts for laughing at a friend whose baggage was waylaid by airline
<elderK>
shka__: I imagine I could force that using the MOP.
<elderK>
shka__: I might even side-step the entire issue and force people to do "structural inheritance" themselves via composition.
<p_l>
Swiss precision unfortunately was not enough to send my baggage to USA
<no-defun-allowed>
):
<p_l>
It seems that everyone who took that transfer was affected, since me and my two coworkers all are in the same predicament
dale has quit [Quit: dale]
rumbler31 has quit [Remote host closed the connection]
<loke`>
p_l: what are you duing in the US?
<p_l>
Team meeting
rumbler31 has joined #lisp
lmy9900 has joined #lisp
robdog_ has joined #lisp
orivej has quit [Ping timeout: 246 seconds]
orivej has joined #lisp
robdog_ has quit [Ping timeout: 252 seconds]
lmy9900 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
robdog_ has joined #lisp
robdog_ has quit [Ping timeout: 268 seconds]
orivej has quit [Ping timeout: 240 seconds]
shka_ has joined #lisp
SlashLife has quit [Ping timeout: 264 seconds]
makomo has quit [Quit: WeeChat 2.2]
clintm has quit [Remote host closed the connection]
shifty has joined #lisp
nolanv has quit [Ping timeout: 272 seconds]
nolanv has joined #lisp
JohnMS_WORK has joined #lisp
shrdlu68 has joined #lisp
Inline has quit [Quit: Leaving]
<flip214>
p_l: so at least the problem is reproducible ;)
shka_ has quit [Ping timeout: 246 seconds]
varjag has joined #lisp
vlatkoB has joined #lisp
lmy9900 has joined #lisp
robdog_ has joined #lisp
drewes has joined #lisp
robdog_ has quit [Ping timeout: 268 seconds]
frgo has quit [Remote host closed the connection]
CrazyEddy has joined #lisp
graphene has quit [Remote host closed the connection]
graphene has joined #lisp
nirved has joined #lisp
angavrilov has joined #lisp
<beach>
A few minutes ago, I started an update of the Trisquel Linux system on my laptop. I am amazed to see a large number of errors and warnings. I think the situation is similar with established Linux distributions like Ubuntu.
<beach>
It looks like, in addition to aiming for a complete Lisp operating system, we should work on writing applications and GUI stuff like a desktop for GNU/Linux in Common Lisp. It could be done very nicely now that McCLIM is quite good (but not perfect of course).
<beach>
End-user application can be written so that they work both on traditional operating systems and on future Lisp operating systems.
robdog_ has joined #lisp
<dim>
so you think that by using Lisp we would reduce the amount of errors and warnings?
<beach>
I do, yes.
scymtym has joined #lisp
<beach>
Some people will disagree of course.
robdog_ has quit [Ping timeout: 252 seconds]
<dim>
my current thinking about it is more related to people and “works for me” classics, either attitude, or diversity of hardware for Linux kernels, or setups or apps, etc
<beach>
I don't understand.
<elderK>
Guys, what is a good way to catch like, a destructuring-bind error?
<elderK>
if destructuring-bind fails, because of bad input, should I just let that error propogate from my macro? Or should I translate it into something more meaningful?
<elderK>
Like instead of just, SOMETHING ERROR: Destructuring BAD!, I could say something like, Oh, hey, this is invalid slot form.
<elderK>
or whatever.
<shrdlu68>
elderK: "If the result of evaluating the expression does not match the destructuring pattern, an error of type error should be signaled."
<elderK>
shrdlu68: Right. The question is whether I let that "low-level" error propogate. Or whether I translate it.
<elderK>
I'm not sure what the usual... like, rules are, for macros that do a lot of destructuring.
<elderK>
Like, not just the things passed to the macro as arguments. I mean like, subforms that we process.
<dim>
beach: I have a hard time thinking that the programming language has such an influence on the quality of the programs, for me it's just that most developers think their job is to write code rather than maintain a solution/service to other users
<beach>
I see.
<dim>
I've seen that a lot when consulting, one of my favorite example is about a web service that was broken because authentication cache was lost, and then the dev team was like “I think I know how to fix it, requires a couple days, plus tests”, and not one of those guys though about how to make it so that users could log in again *now*
<dim>
I think it's a good example because it shows clearly the lack of thinking about the users, in an obvious way with a web service currently broken
<beach>
dim: So I have a question for you. If you don't think the programming language has any influence on the quality of the code, why are you using Common Lisp rather than some more widely used language?
<dim>
note: it's a web service used by about 1 million people a day
<dim>
beach: oh I think the programming language has lots of influence, yeah, just not the influence required to improve how developers think of their activity
ebrasca has joined #lisp
<dim>
it's possible (and easy) to write crappy code in any language, I like CL better myself ;-)
rumbler31 has quit [Remote host closed the connection]
graphene has quit [Remote host closed the connection]
<beach>
dim: My goal was not to change how developers think, only to make it easier to fix problems and to write software with better architecture and better safety.
shrdlu68 has quit [Ping timeout: 250 seconds]
graphene has joined #lisp
<dim>
yeah I agree that CL offers better tooling than most other languages (hence my choice), the software still needs to be written by people who understand and cares about the quality in terms of end-user experience
<no-defun-allowed>
is there a way to to make an "inline" macro?
<beach>
What is that supposed to mean?
<no-defun-allowed>
actually, what i'm describing is closest to eval
<jackdaniel>
programming langugage may provide systematical ways to avoid certain classess of problems (and make fixing some other easier)
<no-defun-allowed>
hmm
<no-defun-allowed>
never mind, beach, just a silly thought that popped in
<jackdaniel>
I also tend to think though that problems which are inherent to some programming languages do not explot whole "crappy software" problem space :)
yvy has joined #lisp
<no-defun-allowed>
#. is probably what i'm thinking of anyway
<no-defun-allowed>
#.(cons '+ (loop for x below 10 collect x)) => (+ 0 .. 9) though that's a bad example
<White_Flame>
well, that's at readtime. What would "inline" at compile time be?
<no-defun-allowed>
well it'd be a macro which takes a expression-making expression in and puts it out, something like (defmacro inline-macro (expander) `(symbol-macrolet ((whatever ,expander)) whatever))
<White_Flame>
hmm, yeah, it'd be without parameters, just code to generate code
<White_Flame>
so symbol-macro makes sense, but without a symbol
<no-defun-allowed>
yeah
anewuser has quit [Ping timeout: 268 seconds]
anewuser has joined #lisp
frgo has joined #lisp
heisig has joined #lisp
frgo has quit [Read error: Connection reset by peer]
frgo has joined #lisp
robdog_ has joined #lisp
frgo has quit [Remote host closed the connection]
frgo has joined #lisp
shrdlu68 has joined #lisp
<_death>
no-defun-allowed: usually such an operator is called META.. some years ago there was discussion here about a related one which I called METALIST :)
<no-defun-allowed>
right
graphene has quit [Remote host closed the connection]
edgar-rft has joined #lisp
pierpal has quit [Quit: Poof]
<_death>
usually macrolet is used and not symbol-macrolet
jochens has quit [Remote host closed the connection]
jochens has joined #lisp
clintm has joined #lisp
<ebrasca>
elderK: Hi
<elderK>
Hey ebrasca!
<elderK>
How's it going?
<ebrasca>
elderK: I am fine , learning some vulkan.
<elderK>
Cool :)
<ebrasca>
Maybe some day mezzano + vulkan.
<elderK>
That would be pretty epic.
yvy has quit [Quit: Leaving]
<elderK>
ebrasca: I'm still working on a binary types system. It might be worth discussing it in #mezzano, to help hash out what is truly necessary
gxt has quit [Ping timeout: 252 seconds]
lucasb_ has joined #lisp
lucasb_ is now known as lucasb
<shrdlu68>
I think languages which insist on using indirections as a matter of course are easier to write crappy software in.
hhdave has joined #lisp
robdog_ has joined #lisp
<shrdlu68>
Indirection as in "indirectness or lack of straightforwardness in action, speech, or progression."
orivej has joined #lisp
<elderK>
shrdlu68: I'm still curious as to how I should handle errors wrt destructuring-bind. Like, do most libraries handle them in some way? Or do they just let the low-level thing propogate? Or perhaps they parse forms differently?
<_death>
elderK: if you care about validation, write an explicit validation routine
<_death>
elderK: then instead of destructuring-bind have your own destructuring macro
<elderK>
_death: Okay. Is this the thing that most people do?
<shrdlu68>
elderK: If you're writing an API, it would be best to do validation explicitly.
<elderK>
:) Still getting a feel for like, what is usual, etc.
<heisig>
elderK: I avoid destructuring-bind and use trivia.
<_death>
elderK: depends on the context.. usually it's overkill, but see shrdlu68's remark :)
<elderK>
Thanks :)
<beach>
elderK: Here are some useful hints with respect to handling exceptional situations: There are basically three kinds of exceptional situations: 1. Defects. 2. Resource exhaustion. 3. Others (part of a control structure). I think you are looking at 1. As long as they are detected and the place where they happen is signaled, you don't have to do anything in particular.
<splittist>
hola #lisp
robdog_ has quit [Ping timeout: 260 seconds]
<elderK>
Helloha splittist
<beach>
Hello splittist.
<elderK>
beach: I guess I'd just like to present a more useful error. Like, if the destructuring-bind error propogates up, like, it's an internal detail. People will be like, okay great, something doesn't work. And the context will be wherever it is. Where as, I would rather say, signal some custom condition that would say like, invalid whatever, etc. They'd know what they did wrong, with respect to using the macro.
<beach>
elderK: If a defect is signaled at the time the end-user is using the program, there is nothing that end-user can do to fix it. If it is detected during development, the programmer should be able to fix it without any particular assistance, as long as the place of the problem is indicated.
<shrdlu68>
elderK: I think having to handle an exception at destructuring-bind means some validation that should have been doen at some point before that wasn't.
<elderK>
Aye.
hhdave_ has joined #lisp
hhdave has quit [Ping timeout: 246 seconds]
hhdave_ is now known as hhdave
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
shrdlu68 has quit [Ping timeout: 240 seconds]
xkapastel has joined #lisp
robdog_ has joined #lisp
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
Odin- has joined #lisp
robdog_ has quit [Ping timeout: 268 seconds]
graphene has quit [Remote host closed the connection]
<ogamita>
dim: it's not the same job, writing/debugging programs, and helping users. In your specific case, helping the users to login back right now would probably involve completely different otols and solutions than correcting the program so the problem doesn't occur in the first place.
robdog_ has joined #lisp
fikka has quit [Ping timeout: 250 seconds]
<ogamita>
I saw that early; it's a career choice to either cater to 1 user, or to develop and debug programs hopefully for millions of users. The former is closer to concierge work really… (not saying it pejoratively, I mean high-end high quality conciergery).
eminhi has joined #lisp
<elderK>
ogamita: Thank you :)
mht has joined #lisp
<elderK>
:P I'm having a trouble with massively long names for things.
<elderK>
invalid-slot-description-slot-name for instnace
<elderK>
:P
<ogamita>
And for programmers, the choice of programming language definitely implies differences in the mental load and the attitude of the programmer, leading to the presence or absence of whole classes of bugs.
<ogamita>
elderK: if you use emacs, there's automatic expansion of names from abbreviated inputs.
<ogamita>
Some modes let you type i-s-d-s-n for example.
robdog_ has quit [Ping timeout: 252 seconds]
<beach>
Doesn't CLIM beat that with some function name?
<elderK>
ogamita: I have no problem typing such a name. But like, iono, it feels very wrong :P
<ogamita>
it's a style. You can choose to use shorter names. The problem is to find meaningful short names.
<beach>
command-line-read-remaining-arguments-for-partial-command is a candidate.
<elderK>
Agreed.
<ogamita>
elderK: the problem of error handing is a general program, it's not specific to a form such as destructuring-bind. Since in lisp so many operators already perform run-time checks and signal errors, you can start by basically ignoring all error conditions, and letting lisp signal them. The advantage: simple, the inconvenient: error messages are not meaningful to the user.
robdog_ has joined #lisp
<ogamita>
elderK: then you can add some validation and error checking at the interfaces. Assuming that the data is validated at the interfaces, you should be able to prove that no error will occur in the internal code. (ah!)
<jackdaniel>
that's another flip of the coin: common lisp makes a space for a class of bugs which are uncommon in statically typed languages (destructuring-bind is a very good example of that actually)
frgo has quit [Read error: Connection reset by peer]
frgo has joined #lisp
<ogamita>
elderK: and finally, you can develop a whole ontology of error conditions, including them in the API, (you can even have conditions that are not signaled in the current implementation,but that could be if the implementation changed!) and you could check or handle all condition very meticulously.
<jackdaniel>
but (+ a b) is a good example either
<ogamita>
in this later case, it is easy to have more LoC about error handling than actual code…
<ogamita>
jackdaniel: not more errors, rather fewer, but distributed differently on the lifecycle of the project.
<jackdaniel>
I'm not talking about quantity now but rather different kinds of issues which may occur in code
<_death>
elderK: in that case you could have a generic function SLOT-NAME with a method that specializes on INVALID-SLOT-DESCRIPTION
<dim>
ogamita: I totally disagree with you, code is not written in the abstract, the goal of writing code is not to have written code, it's there to serve users. If you can't be concerned about users of your code, please stop writing any code.
<ogamita>
The only difference is that since run-time checks must be performed ANYWAYS, because shit happens, lisp always include them so it can spare them at compilation time. Just add tests to detect them at "compilation-and-test" time, instead of at run-time.
<ogamita>
dim: you don't serve the same way 1 user and 1 million or 1 billion users.
<jackdaniel>
we are talking about practices which are encouraged by language design, not about technical possibilities
fikka has joined #lisp
<dim>
sure, what's that to say with the attitude of the developer?
<jackdaniel>
if we had followed this trail we could make up a crappy argument, that c is as safe as cl, because you may write cl in c
<ogamita>
dim: I won't make a judgement, but I notice that developers catering to millions or billions are more wealthy.
<ogamita>
jackdaniel: definitely! So I guess now you compile all your C programs (eg. including ecl) with a whole gamut of -fsanitize options, right?
Demosthenex has quit [Ping timeout: 240 seconds]
<ogamita>
If not, you're just a filthy C programmer :-)
<jackdaniel>
thats a very lousy argument (as I've mentioned a few lines back)
mingus has joined #lisp
<ogamita>
attitude.
<dim>
ogamita: you don't like making relevant points, do you?
<no-defun-allowed>
No, that's not something pjb/ogamita is often good at.
fikka has quit [Ping timeout: 268 seconds]
<elderK>
Aw c'mon guys. Don't beat up on pjb / ogamita :)
<no-defun-allowed>
Dare I say it, linking to your Usenet quote collection is also a bit lazy too.
<ogamita>
dim: I made very relevant points. You are confusing two situation. What you witnessed, was mismanagement, not a programmer problem. The managers made the mistake to hire a programmer when they should have hired an operator.
<no-defun-allowed>
Fine, back to the usual self deprecation.
<ogamita>
In classic IT departments, there's a clear separation between programmers who work on time ranges over months or years, and operators who work on time ranges over hours.
igemnace has quit [Quit: WeeChat 2.3]
sindan has joined #lisp
<no-defun-allowed>
I think that's a bit silly, though I've only had one experience in a normalish development group.
<ogamita>
But even if you do agile and devops and reduce the difference in time scale between the two categories, it still exists. You just witnessed that.
<dim>
ogamita: it's funny that you understand the situation that way, because my point is exactly that the developer should be concerned with fixing the service/application for its users, full stop. You're making the point that dev and ops should be separated. Well, we disagree.
<jackdaniel>
that sounds too much like "people as cogs in a machine" to me, I'll pass on "minding only what's required in job description"
frgo has quit [Ping timeout: 246 seconds]
<elderK>
So, what are the limits you guys usually use for your lines?
<elderK>
76? 80? More?
<dim>
80 or a bit less
<ogamita>
elderK: screen size.
<dim>
eyes sore more from reading left to right than up to bottom
<dim>
so have short lines
<jackdaniel>
elderK: around 80 is good, but breaking a line just for a sake of breaking it doesn't make sense
<no-defun-allowed>
Then again, I was the only one who knew (relatively) how to deploy a Lisp program.
<ogamita>
(frame-width (selected-frame)) -> 191
<z0d>
43 rows; 158 columns;
<z0d>
on my laptop
<jackdaniel>
80 lines gives you three columns with a reasonable font size vs 1080p resolution
<elderK>
I keep my lines <= 80. For me, it's very important that that limit is not breached.
<z0d>
on my desktop it's larger, but I don't remember
<no-defun-allowed>
Usually between 80 to 100, I do cut some slack as Lisp usually has nice clear names.
frgo has joined #lisp
<ogamita>
What seems reasonable to me is to keep indeed 80 columns, but discounting the indentation!
<elderK>
But I am finding it difficult to keep below that limit in some cases.
<ogamita>
So your text may zigzag over more than 80 columns.
<jackdaniel>
being 80-line dogmatic may bite you (i.e you may start refactoring completely fine functions because some method name is too long)
<elderK>
ogamita: I imagine you don't care about like, the margin so much because you know, you can just reformat the sexps to whatever limit.
<no-defun-allowed>
If they do get that long, I consider it a lack of abstraction instead of long names or bad positioning of sexps
<ogamita>
And sometimes, it's easier to read long lines (eg. when you write codes in columns), than to fit it in 80 columns and break the 2D nature of your code.
lmy9900 has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<elderK>
jackdaniel: It's less dogma for me and more necessity. I can only fit so much horizontally on screen due to zoom.
<elderK>
And text size.
<ogamita>
elderK: just because you can scroll laterally as easily as you can scroll vertically. So as long as complete lines are visible, it's ok.
<no-defun-allowed>
Some geometric or aesthetic heuristics like that usually help me write clean code, but I don't see it as a hard constraint.
<elderK>
ogamita: Scrolling horizontally is shit if you wind up spending most of your time moving left/right/left/right constantly.
<elderK>
Say, in a code review.
<ogamita>
You don't need to do that as long as complete lines are visible.
<elderK>
Yes, and if they aren't, then it's horrible.
<elderK>
And in general, you will want to see context around the line in particular you are reading.
<no-defun-allowed>
Another is if there's too many )'s at the end of an expression, I missed something, it's CL-WHO or too much stuff in one function.
<elderK>
In general, if I keep hitting the margin, it is an indicator for me that I may be doing too much in one place.
themsay has quit [Ping timeout: 240 seconds]
<no-defun-allowed>
Exactly.
themsay has joined #lisp
<jackdaniel>
they've once stole 10% of a very sophisticated military code from pentagon. it happened to be written in lisp. sadly all they got was ")))))))))…"
<elderK>
jackdaniel: God, that's an old joke.
<elderK>
:P
<no-defun-allowed>
(Rainbow delimiters in Emacs have a period of about 8, which is the end of my comfort zone.)
<jackdaniel>
you may skip the titles, "jackdaniel: that's an old joke." would be fine
<elderK>
:P
<no-defun-allowed>
That joke is so old, they had to update it when s expressions came around.
<_death>
that's why they invented superparenthesis
<elderK>
I really wish urxvt would match uris over multiple lines
xificurC has joined #lisp
<ogamita>
_death: definitely. Again, it's always the same thing, functional abstractions (sicp etc).
<ogamita>
elderK: I do too. Anyways, M-expressions are just a prototype. It was planed to design a nice syntax for lisp, but since s-expressions caught up, that project never realized.
fikka has joined #lisp
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
jochens has quit [Ping timeout: 250 seconds]
anewuser has quit [Ping timeout: 250 seconds]
jochens has joined #lisp
_whitelogger has joined #lisp
jetchisel has joined #lisp
jetchisel has quit [Ping timeout: 250 seconds]
jetchisel has joined #lisp
jochens_ has joined #lisp
jochens has quit [Ping timeout: 250 seconds]
robdog_ has quit [Remote host closed the connection]
esrse has quit [Ping timeout: 268 seconds]
anewuser has quit [Ping timeout: 250 seconds]
Kaisyu has quit [Ping timeout: 268 seconds]
robdog__ has joined #lisp
groovy2shoes has quit [Excess Flood]
robdog has quit [Ping timeout: 268 seconds]
groovy2shoes has joined #lisp
Kaisyu has joined #lisp
pierpal has quit [Quit: Poof]
pierpal has joined #lisp
anewuser has joined #lisp
orivej has joined #lisp
robdog__ has quit [Ping timeout: 252 seconds]
vlatkoB_ has joined #lisp
vlatkoB has quit [Ping timeout: 250 seconds]
ggole has joined #lisp
fikka has quit [Ping timeout: 250 seconds]
robdog has joined #lisp
<ogamita>
s/caught up/caught on/ Thanks to luis for the bug report. ;-)
robdog has quit [Ping timeout: 260 seconds]
fikka has joined #lisp
anewuser has quit [Ping timeout: 250 seconds]
robdog has joined #lisp
Lycurgus has quit [Quit: Exeunt]
anewuser has joined #lisp
frgo has quit [Read error: Connection reset by peer]
shrdlu68 has joined #lisp
gravicappa has joined #lisp
anewuser has quit [Quit: anewuser]
kajo has quit [Ping timeout: 252 seconds]
bsimjoo has joined #lisp
bsimjoo has quit [Client Quit]
fikka has quit [Ping timeout: 246 seconds]
dddddd has joined #lisp
<jcowan>
dim: (on the broken authentication cache): Sounds like the cache was not a cache but the source of truth for authentication. A lost cache should only have slowed things down, no?
<shka__>
dear #lisp
<shka__>
i want to make a system to handle ICD10 diagnostic medical codes in lisp
<shka__>
such system would contain complete list of relevant codes
<shka__>
however, how should i manage such list?
<shka__>
simply one large lisp file or use CSV?
<beach>
How many are there?
<shka__>
thousands
<Odin->
14000 in the base spec, according to Wikipedia.
<shka__>
Odin-: thank you
fikka has joined #lisp
<beach>
shka__: What are the operations on this list of codes?
<Odin->
Not knowing specifics, I'd wager it's a hierarchical system.
<shka__>
find closest code by name, split existing code into hierarchy, find neighboors, but list remains inmutable as a whole
<shka__>
Odin-: indeed it is
<beach>
shka__: What's the name of a code?
<shka__>
a string, essentially
<shka__>
for instance "R06.2" is Wheezing
<shka__>
other then asthma, to be specific ;-)
<beach>
shka__: When you ask questions like that, you should talk about operations first. A list of the codes (as you initially said) would be of no use.
<beach>
(A00 A01 A02 A03....)
<shka__>
for user, yes, but i need those in implementation
<beach>
I give up.
<shka__>
why?
fikka has quit [Ping timeout: 240 seconds]
<shka__>
:(
<beach>
You said that you wanted to represent a list of code. A list of codes is (A00 A01 A02...). Such a list has absolutely no use.
<Odin->
"X35 Victim of volcanic eruption" ← That's a short code for what can't be too common.
<shka__>
Odin-: :D
<shka__>
beach: ok, agreed
<beach>
shka__: So you did not mean that you wanted a list of codes. You meant something else, and that something else is a description of an abstract data type, which is defined by its operations.
<Odin->
Well, the initial statement was "handle diagnostic codes".
<Odin->
But the main question is "what operations do you need to perform?"
<beach>
That is what I am trying to communicate, yes.
<elderK>
Aye. How you operate on the data kind of leads to what kind of data structure (or structures) you populate / manipulate.
<Odin->
With a structured code system, most of the desired operations _should_ be doable using string manipulations, so there wouldn't be a need to store a complete list of codes.
<shka__>
ok, so let my clarify
robdog has quit [Remote host closed the connection]
<beach>
shka__: Just give a list of the damned operations already.
<shka__>
find closest code by name, split existing code into hierarchy, find neighboors of code (by tree hierarchy)
<beach>
I should take a break. I am in a rotten mood, I can tell.
<shka__>
essentially, just lookup
<shka__>
in some sort of abstract database
<shka__>
what i am trying to figure out is how and when construct this abstract database
<jackdaniel>
I don't understand this discussion. You've asked "what data structure", "for a LIST"(!), "which is TREE"(!)
<elderK>
shka__: But really, you could just... separate it into components easily enough. And build a trie.
* elderK
shrugs
<shka__>
jackdaniel: i am not asking about data structures, i just want to know if loading it during load operation is a good idea
<Odin->
If you're looking up "by name" then you're presumably also working with the descriptions given, so you'd also have an index in the other direction.
robdog has joined #lisp
<shka__>
elderK: it can be done, but i have other (simpler) solution in mind already
<elderK>
shka__: Whatever works. :)
<shka__>
beach: ok, thanks!
jochens_ has quit [Read error: Connection reset by peer]
<elderK>
I'd like to see DreamScheme or something on here :D
<_death>
shka: you can store it in a csv, which is easy to update.. you can provide a function to read it and build the database, and let the user decide when to do that
Cymew has quit [Read error: Connection reset by peer]
<shka__>
_death: wouldn't it be more convinient if it would be loaded up when system is loaded automaticly?
<shka__>
well, i can do both i think...
Cymew has joined #lisp
robdog has quit [Remote host closed the connection]
<_death>
shka: loaded automatically = constraint.. so depends on what you want to provide
<shka__>
well, this list is not updated so frequently
robdog has joined #lisp
drewes has quit [Ping timeout: 244 seconds]
Essadon has joined #lisp
kyby64 has joined #lisp
robdog has quit [Ping timeout: 268 seconds]
frgo has joined #lisp
<flip214>
> Size of download is 1 kB.
<ogamita>
shka__: first it should probably be data. Now the criteria are the volume and the mutability. On one hand, it's relatively sizeable data, you might want to keep on file and load only on a as-needed basis. On the other hand, 14000 items in gigabyte memories is nothing, so it could also be loaded in whole. On the other hand, while it is mutable (it can be updated from time-to-time), we can assume that while the program is running the
<ogamita>
data won't change, so basically immutable. In consequences, choosing to define it in a toplevel form, at compilation-time, and loading it as literal data by loading a fasl file is an option.
skeuomorf has joined #lisp
skeuomorf has left #lisp [#lisp]
<ogamita>
shka__: I don't particularly like this option, I'd rather save the data in a file, and read this file when initializing the application, but given the constraints I listed, saving it in a fasl and loading it as literal data is a quick and easy way to do it.
<ogamita>
shka__: notice that the source of the data base may be a cvs or a PDF from "upstream", and you can process this source at compilation-time!
<dim>
note that we still don't know what's the use of the data… the generic “lookup” answer isn't very satisfying
<ogamita>
One advantage of puting it in a toplevel form and a fasl file, is that if you save an excutable image, the data will be there without having anything to do. On the other hand, if you keep it in a separate data file, once the excutable image saved, you will still have to install the data file along with the executable on the user file system and to load it at run-time.
<ogamita>
dim: imagine it's a big table of error code -> error message code. It basically behave the same.
<dim>
same benefits with a defparameter form.
<ogamita>
Yes.
nicksmaddog has joined #lisp
robdog has joined #lisp
<jackdaniel>
nb: this doesn't play nice if you build the executable (and not dump the image), (defparameter *foo* (load-from-my-file)) if that file is not present at the host system will fail
<dim>
ogamita: I don't know that. I know how error codes in SQL standard and PostgreSQL works, and that's completely static, basically you have a condition class with a sqlcode slot you pick the slot in the code statically depending on the situation
<jackdaniel>
on the other hand (defparameter *foo* #.(load-from-my-file)) will work on both
<dim>
if that's the same thing with this ICD10 then it's easy, just add a icd10 field to your medical-condition condition definition
<dim>
I don't suppose it's the case though
<dim>
jackdaniel: I don't think you even need the #. reader-eval trick here
<dim>
oh I missed the executable vs image dump bits
<jackdaniel>
dim: you need if you do not save the image. toplevel forms are replayed upon start in that case
<jackdaniel>
right
<dim>
I've never done anything else than dump an image to get an executable…
<jackdaniel>
both ecl and clasp build executables from sources
razzy has joined #lisp
Cymew has quit [Remote host closed the connection]
<jackdaniel>
also I can imagine a build system which calls compile-file to have fasls (without loading sources first)
robdog has quit [Remote host closed the connection]
<ogamita>
dim: error messages are not completely static. They change from one version to another. So you need to update that kind of metadata from time to time.
<ogamita>
dim: you need #. to save the data in the fasl file and the lisp image (so it works on both implementations with lisp images, and implementations with elf executables).
<dim>
what I mean is that I don't suppose that the medical application is going to pick the error code depending on machine generated diagnosis, I would suppose it's an input system for a human medic, but we don't know that yet
<ogamita>
I imagine they update the code list every couple of years or so.
<ogamita>
They are several versions of the standard.
<dim>
yeah jackdaniel explained #. before, thanks
<ogamita>
ICD-10-PCS was initially released in 1998. It has been updated
<ogamita>
annually since that time.
<ogamita>
So you will want to update it and generate a new version of the application every year. Which is good, since then you can make pay customers every year :-)
gravicappa has quit [Remote host closed the connection]
<jcowan>
Not so much a human doctor as a human medical clerk, typically.
Demosthenex has joined #lisp
orivej has quit [Ping timeout: 244 seconds]
smokeink has joined #lisp
gxt has joined #lisp
<shka__>
ogamita: that's any option i think
kyby64 has quit [Ping timeout: 246 seconds]
kyby64 has joined #lisp
kajo has joined #lisp
Mr-Potter has joined #lisp
robdog has joined #lisp
fikka has joined #lisp
smokeink has quit [Ping timeout: 246 seconds]
Cymew has joined #lisp
pierpal has quit [Ping timeout: 245 seconds]
Bike has joined #lisp
<ogamita>
shka__: the other option, is to download the data from the web. This means the customer needs an internet connection, so you can check the validity of his license ;-)
<shka__>
heh, well, i am doing this as internal tool so don't worry about it
<ogamita>
So, loading the data in defparameter is the simpliest Q&D thing to do.
<shka__>
yes, i wasn't just sure if it wasn't just too dirty
flazh has quit [Ping timeout: 244 seconds]
<shka__>
but beach says that it is acceptable so i am sticking to this
<ogamita>
For internal tools, it's ok. You use it internally, you have the sources, in case of problems you can correct easily.
FreeBirdLjj has joined #lisp
warweasle has joined #lisp
LiamH has joined #lisp
mindCrime has joined #lisp
drewes has joined #lisp
aja042 has quit [Ping timeout: 246 seconds]
v0|d has quit [Read error: Connection reset by peer]
kyby64 has quit [Quit: Leaving]
shifty has quit [Ping timeout: 268 seconds]
pierpal has joined #lisp
gxt has quit [Ping timeout: 252 seconds]
dale has joined #lisp
nicksmaddog has quit [Ping timeout: 250 seconds]
rumbler31 has joined #lisp
jkordani has joined #lisp
aja042 has joined #lisp
rumbler31 has quit [Remote host closed the connection]
aja042 has quit [Read error: Connection reset by peer]
robdog_ has quit [Remote host closed the connection]
sauvin has quit [Read error: Connection reset by peer]
robdog_ has joined #lisp
eminhi has quit [Ping timeout: 250 seconds]
eminhi has joined #lisp
robdog_ has quit [Read error: Connection timed out]
robdog_ has joined #lisp
meepdeew has joined #lisp
meepdeew has quit [Read error: Connection reset by peer]
varjag has joined #lisp
jochens has joined #lisp
robdog_ has quit [Ping timeout: 260 seconds]
jochens has quit [Ping timeout: 246 seconds]
jmercouris has joined #lisp
<jmercouris>
when I only want to use the second value that a function returns, is there a way to do that without using multiple-value-bind and (declare (ignore first-value)) ?
<dlowe>
nth-value
<jmercouris>
dlowe: thanks!
slyrus1 has quit [Ping timeout: 250 seconds]
malice has quit [Ping timeout: 256 seconds]
<pfdietz>
There should be a place whose effect is to discard the value assigned to it. (values), I guess but can that be used inside another (values ...)?
slyrus has quit [Quit: slyrus]
robdog_ has joined #lisp
<White_Flame>
(defvar /dev/null)
<White_Flame>
but yeah, the store would still occur, while the ideal would be to elide it altogether
xkapastel has quit [Quit: Connection closed for inactivity]
<pfdietz>
(setf (values (values)) 1) errors in sbcl and ccl, works in clisp and ecl.
jmercouris has quit [Remote host closed the connection]
slyrus has joined #lisp
<White_Flame>
yeah, have been trying that sort of thing as well. it seems to expand with a weird NIL injected
robdog_ has quit [Ping timeout: 252 seconds]
robdog_ has joined #lisp
graphene has quit [Remote host closed the connection]
<White_Flame>
(setf (values (values)) 1) seems to be the shortest failure case I can construct
<White_Flame>
erm, nevermind
xkapastel has joined #lisp
graphene has joined #lisp
<White_Flame>
but (setf (values a (values)) (values 1 2)) shows the broken lambda parameters that get expanded
<White_Flame>
in the error message
cage_ has quit [Remote host closed the connection]
anamorphic has joined #lisp
Inline has quit [Read error: Connection reset by peer]
robdog_ has quit [Ping timeout: 252 seconds]
Inline has joined #lisp
scymtym has quit [Ping timeout: 260 seconds]
<dim>
ahah I just did my first implementation of anagrams-p using the prime number products trick, it's fun
<alandipert>
one question i had was, is there an easy way to initialize a struct from a list of slot values?
<Bike>
applying a boa constructor, probably
<Bike>
what do you have in mind here, make-claim?
shifty has joined #lisp
<alandipert>
i didn't care to look but i imagine there's a way to get the list of matched groups from cl-pcre, and so i thought yeah - that function would be tigher if i applied that list to a constructor
<Bike>
if you do (defstruct (claim (:constructor make-claim (id x y width height))) ...) you should be able to call make-claim like (make-claim id x y width height)
<alandipert>
thanks, that makes sense
<Bike>
i don't know if you can do that with ppcre, though, especially since you also need to parse stuff into integers.
<no-defun-allowed>
does anyone have any pointers on making one?
<no-defun-allowed>
my issue would be creating the table at compile time with the correct lexical scoping
<alandipert>
tumdum: thanks! I learned loop 'below' from yours
Kaisyu has quit [Quit: Connection closed for inactivity]
varjag has quit [Quit: ERC (IRC client for Emacs 26.1)]
Kaisyu7 has quit [Quit: ERC (IRC client for Emacs 26.1)]
Kaisyu has joined #lisp
robdog_ has quit [Remote host closed the connection]
Kaisyu7 has joined #lisp
robdog_ has joined #lisp
dacoda has joined #lisp
pfdietz has quit [Ping timeout: 268 seconds]
robdog_ has quit [Ping timeout: 268 seconds]
<fiddlerwoaroof>
alandipert: it's funny, I find using loop improves flow :)
<fiddlerwoaroof>
But, you have to figure out which parts to use
<aeth>
LOOP imo is for ridiculously complicated loops
<aeth>
When you can use something else (e.g. dotimes) use it
<aeth>
e.g. (dotimes (i 4) (dotimes (j 5) (dotimes (k 6) (format t "~D~%" (+ i j k))))) vs. (loop :for i :from 0 :below 4 :do (loop :for j :from 0 :below 5 :do (loop :for k :from 0 :below 6 :do (format t "~D~%" (+ i j k)))))
robdog_ has joined #lisp
<aeth>
And if you have a simple repeated iteration pattern in your code (probably 6 or so times for it to be worth it) that cannot be expressed concisely outside of loop but you can define either a do-foo macro or a higher order function using do/do*/dotimes/loop/map/mapcar/maphash/etc., you should do that imo rather than directly use loop in that case.
<aeth>
But if you're e.g. doing some numerical algorithm that involves stepping through 5+ different variables, using both :with and :for, with a lot of complex logic going on, then you probably should just use LOOP.
pfdietz has joined #lisp
<aeth>
(You could also use DO or DO* for many of these complicated iterations, but then the first thing you'll hear from your peers is "I can't read this")
<alandipert>
do is pretty weird. but I like how weird it is
<aeth>
DO/DO* are great for macro targets, and they're basically just LET with a(n optional) step, a terminator, and a return value.
<aeth>
well, LET or LET*
<aeth>
The three points of confusion are probably (1) the terminating condition is the opposite of what you might expect, (2) the terminating condition and the optional return value are in the same s-expression, and (3) a well-written DO often doesn't have a body at all.
robdog_ has quit [Ping timeout: 252 seconds]
<aeth>
With LOOP you can specify :until/:while, the return is pretty clearly marked, and the step (:for) vs. not-step (:while) forms are clearly distinguished instead of relying on an optional third element in a binding's list.
<eminhi>
Is it better for user macros to target DO/DO* rather than TAGBODY/GO?