beneroth changed the topic of #picolisp to: PicoLisp language | The scalpel of software development | Channel Log: https://libera.irclog.whitequark.org/picolisp | Check www.picolisp.com for more information
seninha has joined #picolisp
pablo_escoberg has joined #picolisp
<pablo_escoberg> To avoid reinventing the wheel, has anyone implemented  pluralize/singularize functionality anywhere (if not sure what that means, this:  https://stackoverflow.com/questions/27194359/javascript-pluralize-an-english-strin)?
seninha has quit [Quit: Leaving]
seninha has joined #picolisp
seninha has quit [Remote host closed the connection]
<abu[7]> Good morning! I did not check all, but it seems the questions are answered?
<abu[7]> I think confusion often comes that people think that namespaces relate do definitions
<abu[7]> They have nothing to do with 'de' or 'dm' etc.
<pablo_escoberg> yes, TY.  with the exception of the last one, but I'm pretty sure the answer there is "no" and I'm most of the way toward implementing it myself.
<abu[7]> They are only concerned about reading
<pablo_escoberg> Well, my primary confusion was thinking that you implemented classes as symbol values.
<pablo_escoberg> So I assumed classes were basically namespaces with some syntactic sugar
<abu[7]> yeah, a class is a symbol
<abu[7]> Namespaces are concerned *only* about I/O
<pablo_escoberg> but the methods are separate from that symbol.  They live in the same namespace as the symbol, rather than having the symbol as their namespace, which was what I assumed.
<pablo_escoberg> the symbol here being the class.
<abu[7]> I cannot imagine how a class should fiddle with namespaces and I/O here
<pablo_escoberg> it shouldn't.  I just thought the implementation was different from what it is.
<abu[7]> A class and its method symbol may reside in different namespaces
<pablo_escoberg> right.  that's where my confusion came in.
<pablo_escoberg> I thought that the class served as the namespace for its methods.  that's how it works in ruby.
<abu[7]> So yes, (local) is needed to enforce local symbols
<abu[7]> I see
<pablo_escoberg> But I get it now.  It's all a lot simpler than what I expect.
<abu[7]> The concept of symbols is unique to Lisp
<abu[7]> Even Scheme doesn't have it as far as I understand
<pablo_escoberg> well, ruby uses the same nomenclature, but ruby symbols are not exactly the same thing.
<pablo_escoberg> similar, though.
<abu[7]> A symbol is *not* a definition
<pablo_escoberg> yeah, especially in Pil.
<abu[7]> T
<abu[7]> A minor detail: (put *Indexes 'T 'id)
<abu[7]> T never needs to be quoted
<pablo_escoberg> cool.  I wasn't sure.
<abu[7]> Some symbols are "auto-quoting"
<abu[7]> NIL, and transient symbols (unless set to a value)
<pablo_escoberg> cool.  but that's the last thing I need to concern myself with right now :D
<pablo_escoberg> anything that works and isn't horrible stays :D
<abu[7]> Indeed :)
<abu[7]> 'T just looks strange to me
<abu[7]> like (+ '3 '4)
<abu[7]> which is also correct
<abu[7]> numbers are auto-quoting too
<abu[7]> and lists starting with a number
<pablo_escoberg> that I actually remember.
<pablo_escoberg> BTW, pluralize/singularize is a nightmare.  It would make for really challenging code golf for those interested in that kind of thing.  I'll post when done, though I imagine the English version I'm making won't be useful to too many...
<pablo_escoberg> OK, so here is the current version of pluralize/singularize:  http://pb1n.de/?4daae5 .  The former is much more complete than the latter.  I'm realizing neither will ever be complete because English is just so weird (I imagine it's substantially more doable in other languages despite gender markers, etc).  However, I will maintain it and
<pablo_escoberg> add/modify it as I find more edge cases. If anyone else uses it and finds an un-handled edge case, please ping me here.
<tankf33der> Morning
<abu[7]> Hi tankf33der!
<tankf33der> abu[7]: i do not see initial email about coredump
<abu[7]> I thought so
<abu[7]> He wrote the mail to me, and the list only in CC
<abu[7]> He attached a long program, with a bit messy code
<abu[7]> I cannot try this here
<abu[7]> He should first debug it by himself I think ;)
<abu[7]> The code is hard to read, violates many pil conventions
<tankf33der> Can i get a copy?
<abu[7]> sure, it is 3 mails in fact
<abu[7]> I'll bounce them to you
<abu[7]> to ...@disroot.org ?
<tankf33der> yea
<tankf33der> i will write him directly without list
<abu[7]> ok
<abu[7]> The others on the list don't have the context
pablo_escoberg has quit [Ping timeout: 246 seconds]
<tankf33der> no crash
<tankf33der> http://ix.io/4C7F
<abu[7]> Indeed
<abu[7]> As I wrote in the mail, I don't think it has to do with the "+"
<abu[7]> It is a heisenbug
<abu[7]> But it crashes in 'idx' somewhere
<tankf33der> a monster script
<tankf33der> insane code just to print
<beneroth> heisenbug in pil is usually redefining a function/code while evaluating it. Maybe you can find something like that in the code?
<beneroth> e.g. a (load) in a function which redefines the current evaluating function?
<beneroth> just a thought, I didn't look at anyhting.
beneroth has quit [Remote host closed the connection]
beneroth has joined #picolisp
<tankf33der> it is impossible to find a crash bug if it is not crashing.
<abu[7]> yeah
<beneroth> xD
<beneroth> T
<beneroth> ¯\_(ツ)_/¯
seninha has joined #picolisp
seninha has quit [Remote host closed the connection]
seninha has joined #picolisp
seninha has quit [Remote host closed the connection]
pablo_escoberg has joined #picolisp
pablo_escoberg has quit [Quit: Client closed]
<abu[7]> j
pablo_escoberg has joined #picolisp
<pablo_escoberg> It looks like I am still missing something basic about the way namespaces work.  So, I get this:
<pablo_escoberg> : (intern '+Rest 'rst)
<pablo_escoberg> -> "+Rest"
<pablo_escoberg> : (intern '+Rest 'rst)
<pablo_escoberg> -> "+Rest"
<pablo_escoberg> : (who '+Rest)
<pablo_escoberg> -> (pico)
<pablo_escoberg> Given the docs, I would expect the result to read `(rst)`.  Why is it now moving the namespace?
<pablo_escoberg> Also, given the above, why does this happen:
<pablo_escoberg> : (get 'pico '+Rest)
<pablo_escoberg> -> NIL
<pablo_escoberg> Apparently, symbols are not stored in namespaces the way I thought, either.  Please enlighten.  BTW, I'm also using `(local)` before all of this, which I also thought would cause the classes to be interned the way I want.
<abu[7]> You can check a namespace with (all 'rst). Gives a list with all symbils in 'rst'
<abu[7]> Concerning your examples like (intern '+Rest 'rst), it all depends on (1) what the current namespace is and (2) where '+Rest' resides in already
<abu[7]> Keep in mind that *reading* an expression like (intern '+Rest 'rst) already finds or interns a symbol like '+Rest'
<pablo_escoberg> hmm...  even if I tell it a specific namespace?
<abu[7]> Remember, we have read-eval-loop
<abu[7]> So *first* the expression is *read*
<abu[7]> if you have (symbols 'rst 'pico)
<abu[7]> and +Rest is alreay in pico, it is found and interned also in rst
<pablo_escoberg> I do have that.  and then I have `(local) (+Rest)`
<abu[7]> could also be done with 'import'
<abu[7]> *if* +Rest already *is* in 'rst' then this one is found and intern is a no-op
<pablo_escoberg> but if I have the symbols and local in place, why is it being interned into 'pico in the first place.
<pablo_escoberg> right.  I wasn't expecting to need to do that given that I already called `(local)`
<abu[7]> given what?
<abu[7]> ok, what is the current search order?
<pablo_escoberg> hang one, let me put the file up on pb1n
<abu[7]> no
<abu[7]> Let's do it step by step
<abu[7]> 1. what is the current search order?
<pablo_escoberg> (symbols 'rst 'r 'pico)
<abu[7]> and you did (local) +Rest
<abu[7]> in that search order?
<pablo_escoberg> that is the next line.
<pablo_escoberg> yes
<abu[7]> good
<beneroth> pablo_escoberg, it seems to me you are (in general) trying to much new at the same time, without taking the proper time to grok it, working with untested wrong assumptions
<abu[7]> (all 'rst)
<abu[7]> should contain +Rest
<pablo_escoberg> it doesn't.
<pablo_escoberg> : (all 'rst)
<pablo_escoberg> -> ("uid" "Ent" "get>" "post>" "perms" "+Rest" "perms>" "+Venue" "Entity" "delete>" "process_query" "current_user" "get_index" "owner_col>" "entities" "*Indexes" "owner_at_creation" "owner_at_creation>")
<abu[7]> Must be as you did (local) +Rest
<abu[7]> Can't be!
<pablo_escoberg> hang on.  let me load the file on its own.
<abu[7]> You dont have rst in your search order
<abu[7]> because all appear as transients!
<abu[7]> Do it in the REPL step by step
<pablo_escoberg> ok, now it's there.  For some reason it was getting clobberred by the other file.
<abu[7]> ok
<abu[7]> 'import' is normally not needed
<pablo_escoberg> but said other file, only has the following that deals with namespaces:
<pablo_escoberg> (symbols 'entities 'rst 'pico)
<pablo_escoberg> (local) (+User +Venue +Vendor +Event)
<pablo_escoberg> and then the class defs
<pablo_escoberg> so how come everything is ending up in 'pico ??
<abu[7]> Can't be :)
<pablo_escoberg> I know!
<abu[7]> New symbols are always created in the *first* namespace in the order
<pablo_escoberg> that's the behavior I expect.
<abu[7]> T
<abu[7]> The whole list is searched, but if not found it is created in the first one
<pablo_escoberg> There is a total of 3 files loaded.  none of them do anything like import or anything.
<abu[7]> And each file calls 'symbols' at the beginning?
<pablo_escoberg> ok, this is interesting.  Now, with all files loaded, everything is in the right namespace, but also in 'pico.  so (who '+Rest) yields 'pico even though it's also in 'rst.
<pablo_escoberg> that's surprising for two reasons.  First, given the search order, I would expect it to show the first namespace in that order.
<abu[7]> 'who' may be wrong here
<abu[7]> You mean 'nsp'
<abu[7]> (nsp '+Rest)
<pablo_escoberg> still says 'pico
<abu[7]> So you 'read' this symbol somewhere while in pico
<abu[7]> If you mention it somewhere, it is created :)
<abu[7]> Probably another symbol
<abu[7]> Try (== 'pico~+Rest 'rst~+Rest)
<abu[7]> Probably two different symbols
<pablo_escoberg> ok, that actually makes sense, and isn't a big issue.  But I still get:
<pablo_escoberg> get 'rst '+Rest)
<pablo_escoberg> -> NIL
<abu[7]> 'get' is wrong here
<abu[7]> (memq '+Rest (all 'rst))
<abu[7]> (nsp '+Rest)
<pablo_escoberg> Oh, so then I probably won't want to use a namespace for this but just a regular symbol (I thought namespaces would be symbols with the various definitions in their properties).
<abu[7]> Namespaces have nothing to do with definitions
<abu[7]> bbl
<pablo_escoberg> OK, cool.  I'll definitely want an expanation for that statement...
<pablo_escoberg> but whenever you get the time.  For now, I'll just restructure where my entities live.
<beneroth> pablo_escoberg, my recommendation would be to just not use namespace for now
<beneroth> you don't need to use them, only for libraries it's recommended to prevent name collisions, but namespacing it can easily be added later. or left away, so it can be decided entirely by the loading code (the loading code can always load a file into a different namespace if it wants to)
<beneroth> when you work with namespacing, you have to ensure the same load order in all your related code.
<beneroth> I hardly use namespaces.
<abu[7]> ret
<abu[7]> Explanation for "Namespaces have nothing to do with definitions" ?
<beneroth> namespaces in pil are part of the "READ" step in REPL (Read Evaluate Print Loop)
<abu[7]> Exactly
<abu[7]> (and a little bit for PRINT)
<beneroth> which is quite different from most other languages, where namespaces are about definition scoping
<abu[7]> A symbol consists of 3 parts: Value, Properties and Name
<beneroth> hence habits about namespacing from other languages don't transfer to picolisp
<abu[7]> Namespaces are only about the names
<abu[7]> How names map to symbols
<abu[7]> That's all
<abu[7]> Definitions are Values
<pablo_escoberg> Ah!  OK.  That really helps.  I thought they mapped names to values. I will need a different mechanism to store my entities.  Probably in the properties of a symbol.
<abu[7]> Sounds good
<abu[7]> tankf33der: Did you try to invoke Jason's program the way he describes it?
<tankf33der> yes, no crash on Fedora and ArchLinux
<tankf33der> it prints routes successfully
<abu[7]> ok
<abu[7]> so heisenbug
<tankf33der> asked him send me output from related commands to me
<tankf33der> i want to be sure this is not pil's issue
<pablo_escoberg> beneroth that's an excellent insight.  I was totally trying to use namespaces to avoid naming conflicts, and it doesn't seem to be working.  How do you do scope segregation in Pil?
<abu[7]> namespaces are exactly there to avoid naming conflicts
<abu[7]> You may have different symbols with the same name
<abu[7]> That's the whole purpose
<abu[7]> Try (shadows T) to see shadowed symbols
<abu[7]> For example, if in 'vip' namespace, we have shadowed symbols:
<abu[7]> : (symbols)
<abu[7]> -> (vip pico)
<abu[7]> vi pico~vi
<abu[7]> : (shadows T)
<abu[7]> cmd pico~cmd
<abu[7]> tag pico~tag
<abu[7]> prev pico~prev
<abu[7]> shift pico~shift
<abu[7]> change pico~change
<abu[7]> -> (vi cmd tag prev shift change)
<pablo_escoberg> and that means they live in two namespaces at the same time?
<abu[7]> These symbols are local to Vip, with other definitions than those with the same name in 'pico'
<abu[7]> yes, of course
<pablo_escoberg> ah, ok.
<abu[7]> There is a 'vi' in 'pico' and another 'vi' in 'vip'
<pablo_escoberg> here's a question:  `all` returns an unquoted list for the currently active namespace, but quoted atoms when not in the namespace.  Why is that?
<abu[7]> Completely unrelated, just the same names
<abu[7]> Sigh! Why *unquoted* list?!!
<pablo_escoberg> well, the atoms are not in quotes.
<abu[7]> Why shoud anytyhing return a *quoted* list?
<abu[7]> or quoted atoms?
<abu[7]> quote is a function!
<abu[7]> Makes no sense as part of data
<pablo_escoberg> it shouldn't.  the thing is `all` behaves differently depending on the namespace that is active.
<pablo_escoberg> I used the wrong verbage.
<abu[7]> ah
<abu[7]> you mean "transient" syms
<abu[7]> ok
<abu[7]> If a symbol is not found in the current search order, it is transient
<pablo_escoberg> aha!
<pablo_escoberg> and yes, quoted means different thing in lisp than in other languages.  need to get used to the terminology too.
<abu[7]> Sorry, I misunderstood
<pablo_escoberg> not at all.  my fault completely.
<abu[7]> Let's call them transients
<pablo_escoberg> indeed!
<abu[7]> : (symbols 'ap 'pico)
<abu[7]> -> (pico)
<abu[7]> ap: (local) (foo A)
<abu[7]> ap: (de foo (A) (inc (* A A)))
<abu[7]> -> foo
<abu[7]> ap: (symbols 'pico)
<abu[7]> -> (ap pico)
<abu[7]> : (pp 'ap~foo)
<abu[7]> (de "foo" ("A")
<abu[7]> (inc (* "A" "A")) )
<abu[7]> -> "foo"
<abu[7]> foo and A are transient now
<pablo_escoberg> yes, that explains the behavior.
<abu[7]> : (all 'ap)
<abu[7]> -> ("A" "foo")
<abu[7]> : (symbols 'ap 'pico)
<abu[7]> -> (pico)
<abu[7]> ap: (all 'ap)
<abu[7]> -> (A foo)
<abu[7]> Not not transient any more (accessible by 'read')
<pablo_escoberg> right, so as long as the namespace is active, I can just collect the classes using `all` and dump them in a symbol's properties.  I just need to make sure the right namespace is active.
<pablo_escoberg> or I guess the correct term is "in the search order"
<abu[7]> Both are good I think
<tankf33der> abu[7]: i have got files and it crashes
<abu[7]> Great! Can you try to locate the problem?
<tankf33der> i have 5min before bed and will continue tomorrow
<tankf33der> (traceAll) works only in debug mode, but i need it without +
<abu[7]> Yeah
<abu[7]> And no hurry
<abu[7]> Good night!
<tankf33der> (gc 16) does not crash
<abu[7]> I thought about trying gc too
<abu[7]> Typical start for such bugs :)
<tankf33der> afk.
<abu[7]> Me too
seninha has joined #picolisp
<pablo_escoberg> there isn't a non-debug version of `dep`, is there?
seninha has quit [Quit: Leaving]
<beneroth> pablo_escoberg, you can do (show 'dep) in debug mode. (show) prints a symbol, its value, and its properties to stdout. in debug mode, (dm) and (de) attach additional property *Dbg which holds the name of the file where it is defined.
<beneroth> this leads you too @lib/debug.l where you find the dep definition/bindings. the implementation uses the functions dep1 and dep2 which are at beginning of debug.l put into a private namespace specific to this file.
<beneroth> so quick & dirty: just copy these 3 functions into your code, to work with them. slightly improved version would be to make dep1 and dep2 transients (both in the definition and call). you could also put all three definition calls into a (unless dep ...) call, so it only gets defined if its not defined anyway (because of debug mode).
<beneroth> everything in picolisp can be inspected :-)
<pablo_escoberg> awesome.  thanks much.
<beneroth> no magic. just building blocks. stratified design. https://ericnormand.me/podcast/lisp-a-language-for-stratified-design
<pablo_escoberg> cool.  I don't really do podcasts (no patience) but I'll have a look at the linked book.
<beneroth> there is a transcript to read too
<pablo_escoberg> oh, cool.  those are usually a pain, but def easier for me than listening to the podcast.
<beneroth> though the guy is a functional programming preacher, mostly home in clojure. so picolisp perspective is a bit different, but in agreement with most he tells
<beneroth> also he discusses turing medal speeches. good papers.
<beneroth> fundamental software design stuff.
<pablo_escoberg> nice.  thanks for the goto
pablo_escoberg1 has joined #picolisp
pablo_escoberg1 has quit [Client Quit]
pablo_escoberg has quit [Ping timeout: 246 seconds]
pablo_escoberg has joined #picolisp
beneroth has quit [Ping timeout: 260 seconds]