<Friithian>
I am using irssi which is in a terminal
<teepee>
yes, that works in quassel too, not flashing though which is good :)
<teepee>
red background, blue foreground
<Friithian>
I have the red background blue foreground, but it is also flashing
<teepee>
you may need to use /quote to get stuff through unchanged
<peepsalot>
hello ? This is some colored text from hexchat
<teepee>
yep, that works
<Friithian>
looks good on both my clients, although konsole is showing that dark orange differently
<Friithian>
[31m maybe \x1B[32m is a weird way of doing it that may not always work
<peepsalot>
doesn't look like I have any way to change bg color though
othx has quit [Ping timeout: 244 seconds]
rawgreaze_ has quit [Changing host]
rawgreaze_ has joined #openscad
rawgreaze_ is now known as rawgreaze
othx has joined #openscad
<peepsalot>
redrum
<peepsalot>
lol i typed redrum with some right to left override
<peepsalot>
testing
<teepee>
good old kthx had a unicode bug at some point too, every 4 byte sequence did kill the poor thing
<peepsalot>
i don't know how these unicode control characters work
<teepee>
othx: status?
<othx>
Gthx.NET version 2.25 2022-05-30: OK; Up for 2 minutes, 10 seconds; mood: pretty good.
<teepee>
yep, I'd say that was a crash :)
<teepee>
botsnack!
<othx>
YUM! This is why I love #openscad.
<teepee>
from the timing, it might have been your normal color though as it had the ?
<teepee>
so colored hello?
<peepsalot>
ping timeout was 6 minutes, so it was probably GunqqerFriithian's "how about this" that did it
<Friithian>
oh shit
<GunqqerFriithian>
how about this
<Friithian>
science!
<peepsalot>
er, wait, 4 minutes, i can't do math
<teepee>
hmm, true, but only up 2 minutes
<teepee>
maybe it has delay before restart
<teepee>
othx: status?
<othx>
Gthx.NET version 2.25 2022-05-30: OK; Up for 7 minutes, 9 seconds; mood: pretty good.
<teepee>
no, still alive
snakedGT has quit [Read error: Connection reset by peer]
snakedLX has joined #openscad
<JordanBrown[m]>
Several of the colored variants came through both on IceChat (my IRC client) and on Element, but I don't know how to type them on either.
<teepee>
I still suspect the hello as the ? is the response trigger, it should not react much to other messages
<JordanBrown[m]>
Test message
<JordanBrown[m]>
* Test message - what happens in IRC if I edit it?
<JordanBrown[m]>
So that was me typing "Test message" and then going back in Element and editing it.
teepee has quit [Remote host closed the connection]
<JordanBrown[m]>
I just wish that I could ditch the two left sidebars in Element.
<JordanBrown[m]>
Actually, the three left sidebars and the right sidebar.
<JordanBrown[m]>
yes, though dinner is close to ready
<InPhase>
JordanBrown: I have a time window. Where would be the optimal place for me to be directing my attention amidst these many discussions and documents I was inattentive to about the object issues.
<JordanBrown[m]>
Selfishly, I think that the glossary that I put into one of the Github discussions would be a good place to start.
<JordanBrown[m]>
Hold a moment and I will find it.
<InPhase>
Excellent. Thanks. (I've bookmarked that wiki one as well.)
<InPhase>
Okay, I reviewed the glossary suggestion carefully, bookmarked it, and concluded that eventually this should probably be documented somewhere more permanent like the manual (upon these becoming instantiated as real). My only suggested change is "optionally" here as: "an executable subprogram that optionally takes data values as input"
<InPhase>
It is a solid summary.
<InPhase>
I will note also that the glossary reflects my current understanding of the right approach following our discussions here.
<InPhase>
The only caveat is that "literal" is used throughout the code where "reference" is proposed in the glossary, but the usage of the term "reference" for this is in fact quite sensible. And in fact with the garbage collector added, they behave quite definitively like references.
<InPhase>
It would be a fair choice even to update the code to match this terminology, eventually, so that we minimize confusion.
<InPhase>
teepee: That would be a thing to flag to your attention, as I believe I recall you were the implementer of function literals for us, and thus would be best position to object if it is a great sin. https://github.com/openscad/openscad/pull/3087#issuecomment-1244103228 Jordan's proposed glossary here puts a nuanced division between "literal" and "reference" that might grow in importance as we end up
<InPhase>
with 3 types of these.
<InPhase>
teepee: This is one of those "no rush" sorts of things. :) More of consensus building.
<InPhase>
Not your fault for missing it. It was missing from the index page.
<InPhase>
JordanBrown[m]: Note, I just discovered this wiki system does not setup redirects like wikimedia on a rename, so you might need to edit any existing links within discussions. (Which I would have brought up before renaming it if I knew there wouldn't be a redirect.)
snakedLX has quit [Ping timeout: 244 seconds]
<JordanBrown[m]>
It seemed important to distinguish the syntactic construct that let you put a function (or module or object) inline, from the data type that resulted from that construct and could be passed around.
<peepsalot>
InPhase: formally, the "literal" is the right hand side of the assignment as in: foo = function() x+1; but then informally we also tend to call foo a function literal as well
<JordanBrown[m]>
I think there was only one link to OEP7 (at the bottom of the glossary comment); I updated it.
<JordanBrown[m]>
Is there a convention for commenting on Wiki pages?
<peepsalot>
just like "hello" is a string literal, and 1337 is a number literal, etc.
<JordanBrown[m]>
Yes, exactly.
<InPhase>
JordanBrown[m]: Midway through my editing blitz, and just checked back. Which aspect of distinguishing do you mean?
<InPhase>
JordanBrown[m]: I am perhaps mentally in the space of something like a language standard, where the operational effects are the critical things being described at this point. I acknowledge the data is there, but am trying to describe only the current choices for its access.
<InPhase>
i.e., observable effects.
<InPhase>
I can add something regarding internal implementation notes if you can clarify which aspect you think should be clarified for that.
snakedLX has joined #openscad
<InPhase>
Something about the CSG tree perhaps? (As this was what I brutally took the scythe to.)
<JordanBrown[m]>
Like peepsalot said, in "x = function (v) v+1;" the "function ..." part is a function literal, but after that assignment x is not a function literal... it is something else, a data value that points to a function.
<InPhase>
History is preserved in this wiki at least up until you rename it. Fortunately I renamed it before making any other changes, so at least up to your last edit is still there. (Kind of a weak wiki system to be honest.)
<JordanBrown[m]>
Informally, all of
<JordanBrown[m]>
function f(x) =v+1;
<JordanBrown[m]>
x= function(v) v+1;
<JordanBrown[m]>
x
<JordanBrown[m]>
are functions
<InPhase>
Oh. Sorry, you're talking about literal vs reference.
<JordanBrown[m]>
but it seems appropriate to distinguish between them when being formal.
<JordanBrown[m]>
yes, exactly.
<InPhase>
Yeah, absolutely, agreed. :)
<JordanBrown[m]>
Must run again, dessert ready.
<InPhase>
I thought you were commenting on my wiki edits as I was doing them. :)
<InPhase>
I'll wait for later comments.
qeed__ has joined #openscad
qeed_ has quit [Ping timeout: 250 seconds]
<JordanBrown[m]>
I was responding to your "which aspect of distinguishing" question.
<InPhase>
JordanBrown[m]: There, I finished my edits. I cleaned up a lot of stuff, favoring an aggressive clean-up, as it's safe in the history (I think) if we need to revert. I left the "Historical Notes Follow" at the end in large part because it's late and now I'm too tired to continue. :)
<JordanBrown>
I'm looking through the revisions as of a few minutes ago; I'll do an additional pass looking at more recent diffs.
<InPhase>
The last edit I made about "each" in modules was sort of an unexpected consequence, but it follows naturally. We will have to think a bit about how that works with the current ordering of lookups of variables, but it turns out we are going to have to do that anyway if it's not correct, because objects make these pretty dynamic. I think nothing of that is currently happening too early in processing
<InPhase>
stage, as for example: module Foo(obj) { x = size; } currently produces no warnings if Foo(5); is not invoked, which says the warning of size not existing is purely at evaluation time.
<InPhase>
Thus, we're fine dynamically altering it based on expanding objects into the context.
<JordanBrown>
I don't understand what you are saying.
<InPhase>
Also, they can expand into the top level, but that was less easy to write as an example in that format.
<InPhase>
Well, you will after reading the last diff.
<InPhase>
(I think.)
<JordanBrown>
:-)
<JordanBrown>
I don't think that much is more dynamic than it is today, but maybe I misunderstand.
<InPhase>
I think we're okay. It's just a leaky consequence of the proposal because objects expand out the other way, as a consequence of making merging work. But I think, after considering it, that this is an elegant symmetry, and might even be convenient sometimes.
<JordanBrown>
Disregarding geometry, I don't think { ... } is any more dynamic than [ ... ].
<InPhase>
Perhaps it also permits some horrible code if people abuse it.
<JordanBrown[m]>
Absolutely.
<InPhase>
(I'm referring there specifically to "each obj;")
<InPhase>
I skimmed over the object() PR a bit while editing, but I am concerned that syntax does not fit well, and was verging too far into trying to be a dictionary like teepee had dropped in that PR comment.
<JordanBrown[m]>
As I have just written in the e-mail message with review comments, how would this hypothetical dictionary type be different from objects? Why would we want to have two different types?
<InPhase>
I had actually considered trying to morph in some dictionary-like features, and evaluated a few other syntax options different from the one in this proposal or in the PR. But at the end of the day I think that's probably going off the rails a bit mixing concepts. We could have dictionaries of objects or objects with dictionaries without confusing ourselves about the two.
<JordanBrown[m]>
(And yes, I know that Python has both, and I have never understood why.)
<InPhase>
Oh I fully endorse a dictionary type. But let's keep that a simple dictionary type.
<JordanBrown[m]>
How would it be different?
<InPhase>
Primarily that dynamic construction methods would be different.
<JordanBrown[m]>
There certainly might be multiple construction techniques, but why would they result in different data types?
<JordanBrown[m]>
Ignoring geometry for a moment, objects are a name-value map. Why do we need more than one name-value map type?
<InPhase>
You could construct keys on the fly by concatenating strings and things like that, and access values by strings that you can manipulate. You could also access things by integer keys well outside of the bounds of a list.
<JordanBrown[m]>
We can already access object values by strings that you can manipulate :-)
<InPhase>
d[-5] should be valid, for example.
<JordanBrown[m]>
Are you referring to something with keys that are not strings?
<InPhase>
d[str("part", i)] as another example.
<JordanBrown[m]>
that already works.
<JordanBrown[m]>
in the dev snapshot, of course.
<InPhase>
For dictionary or objects?
<JordanBrown[m]>
objects
<InPhase>
Well, that proposal is trying to be a dictionary.
<InPhase>
But like, partly one. :)
<InPhase>
I disliked it when I sat down and tried to write an object comprehension.
<JordanBrown[m]>
x = fontmetrics();
<JordanBrown[m]>
echo(x[str("nom","inal")]);
<InPhase>
I came up with something like: obj = { for (k=["a", "b"]) [k] = other_obj[k]; }
<JordanBrown[m]>
Yes, it is not obvious how to write object comprehensions with this proposal.
snakedLX has quit [Ping timeout: 244 seconds]
<JordanBrown[m]>
Though note that you can indirectly write them by passing a list comprehension to object().
JordanBrown has quit [Quit: IceChat - It's what Cool People use]
<InPhase>
Which... works maybe, except it's basically just pretending to be a dictionary? Also that "[k] = " syntax is a little wonky, but the best I could devise without a notion of this or self.
<InPhase>
I thought "each" expansion gave most of the functionality of that, but without trying to go overly dynamic on string accesses.
<JordanBrown[m]>
It'll let you do a couple of things that object() can do, but only a couple.
<JordanBrown[m]>
object() can take an object and produce a modified copy of it, with additions, replacements, and removals.
<InPhase>
To use them as proper dictionaries with integer keys, we're going to end up with abominations like: str("val", i) as keys.
<InPhase>
And that will fail for negatives, so then we need to special case negatives...
<JordanBrown[m]>
See previous comment asking if you're talking about using non-strings as keys.
<InPhase>
So we'll need a wrapper function to do str("valn", abs(i)) if i is negative. It's kind of a bit of a mess.
<InPhase>
Yeah, non-string keys would be a common need.
<JordanBrown[m]>
Why wouldn't a key of str("val", i) work for negative i?
<JordanBrown[m]>
Well, note that JavaScript doesn't have non-string keys...
<InPhase>
Well because "val-5" is not a valid variable name.
<JordanBrown[m]>
Who said it had to be a valid variable name?
<InPhase>
If it's not, you cannot access it as an object variable name, which is a bit awkward.
<JordanBrown[m]>
Works fine in JavaScript.
<InPhase>
I'm goign to just ignore anything about working fine in JavaScript. ;)
<JordanBrown[m]>
If your key follows identifier syntax, you can use obj.key; if not, you have to use obj["key"].
<JordanBrown[m]>
Practically, I'd say that people use obj.key when they are using static names, and obj["key"] when they are using calculated keys.
<JordanBrown[m]>
But the two are formally interchangeable for identifers.
<InPhase>
That approach could be made functional, but it's not particularly elegant, is I suppose my core response to it.
<JordanBrown[m]>
And indeed people will often do
<JordanBrown[m]>
(in JS)
<JordanBrown[m]>
obj = { a: 1, b:2 };
<JordanBrown[m]>
for (k in obj) print(k+"="+obj[k]);
<JordanBrown[m]>
that is, setting values using identifiers, but stepping through them using the calculated-key syntax.
<InPhase>
Also that whole thing about object() taking name=value, [name, value], or lists of [name, value], most likely has to go, because there is too much room for accidental ambiguity there.
<JordanBrown[m]>
Where?
<InPhase>
That's going to be chaotic to use. Every time we have done that, like with search, it has resulted in a disaster.
<InPhase>
I had seen that in the wiki proposal I was editing, but I assumeit followed from a section of the object() PR that I skimmed over.
<JordanBrown[m]>
Hmm... I won't say that it's impossible to get confused, but I find it hard. Then again, that design is largely derived from some of my ideas.
<InPhase>
There should be an obvious processing step for inputs to dynamically construct an object, rather than dynamic inspection of the nesting of the data.
<JordanBrown[m]>
It's less ambiguous than, say, concat().
<InPhase>
This is what led me to consider object literals instead. But then I realized we're just talking about dictionaries.
<InPhase>
Corection...
<InPhase>
This is what led me to consider object comprehensions instead. But then I realized we're just talking about dictionaries.
<JordanBrown[m]>
You mean having to look to see whether it's [[string,value],...] or a single [string, value]?
<InPhase>
If they ARE to become pretend dictionaries though, then construction should probably look like some sort of object comprehensions instead of dynamic input inspection, so that we can empower the same behavior without the ambiguity about intent for an input.
<InPhase>
Yes.
<JordanBrown[m]>
I'd be amenable to dropping the singleton [string,value] construct, but it does seem like a useful shortcut.
<JordanBrown[m]>
Note that these produce the same output:
<JordanBrown[m]>
echo(concat([1],2));
<JordanBrown[m]>
echo(concat([1],[2]));
<InPhase>
Vestiges of the dark times that brought us search(). :)
<JordanBrown[m]>
and that's actually ambiguous; given the first, you'd expect that the second would produce [1,[2]].
<InPhase>
Long live the era of "each".
<JordanBrown[m]>
search is really really dark.
<InPhase>
Yeah, that concat behavior is somewhat treacherous when it's concat(a, b) and they are dynamically pulled from other values. You can get unexpected flattening.
<InPhase>
I guess each is no better there... I just confirmed echo([each 2]); produces [2].
<InPhase>
On that note I will give up for tonight and sleep. :)
<JordanBrown[m]>
I'll have a review message in your mailbox when you awake :-)
ur5us has quit [Ping timeout: 244 seconds]
epony has quit [Remote host closed the connection]
RichardPotthoff has quit [Remote host closed the connection]
RichardPotthoff has joined #openscad
califax has quit [Remote host closed the connection]
califax has joined #openscad
aiyion has quit [Remote host closed the connection]
aiyion has joined #openscad
teepee has quit [Ping timeout: 258 seconds]
little_blossom has quit [Ping timeout: 244 seconds]
califax has quit [Remote host closed the connection]
califax has joined #openscad
pa has quit [Ping timeout: 265 seconds]
teepee has joined #openscad
ur5us has joined #openscad
ur5us has quit [Remote host closed the connection]
ur5us has joined #openscad
pah has joined #openscad
ur5us has quit [Ping timeout: 244 seconds]
pah is now known as pa
epony has joined #openscad
snakedLX has joined #openscad
snakedLX has quit [Client Quit]
teepee_ has joined #openscad
teepee has quit [Ping timeout: 258 seconds]
teepee_ is now known as teepee
teepee has quit [Remote host closed the connection]
teepee has joined #openscad
noonien6 has joined #openscad
noonien has quit [Ping timeout: 265 seconds]
noonien6 is now known as noonien
othx has quit [Ping timeout: 265 seconds]
othx has joined #openscad
<tcurdt>
since sweep from the list comprehension wants points - is there a way to convert a 2d shape into points?
<tcurdt>
I basically want to extrude a 2d shape with a bit more control than linear_extrude
<tcurdt>
...or use skin over multiple 2d shapes
<teepee>
normal openscad, no. there's a pull request making that available but it's not finished and integrated
<tcurdt>
I remember seeing something like that. alright
<J1A8478546163>
tcurdt you can use the svg export .. within that file you have points. (dxf may work too)
<teepee>
hmm, I suppose a polygon/polyhedron export would also be useful and pretty simple to do
<J1A8478546163>
i guess we already have the export.. so the import as points would be the key or how would your idea work?
J1A8478546163 is now known as J1A84
teepee has quit [Remote host closed the connection]
califax has quit [Write error: Broken pipe]
aiyion has quit [Remote host closed the connection]
califax has joined #openscad
aiyion has joined #openscad
teepee has joined #openscad
aiyion has quit [Remote host closed the connection]
aiyion has joined #openscad
<peepsalot>
<InPhase> I guess each is no better there... I just confirmed echo([each 2]); produces [2]
<peepsalot>
you would rather have it produce an error?
<JordanBrown[m]>
Maybe. That variation is less of a concern than concat(), because if you observed that concat([1,2],3) yields [1,2,3] you might reasonably expect that concat([1,2],[3]) would yield [1,2,[3]]) and it doesn't. It seems unlikely that you would deliberately say "each 3" and so you wouldn't extrapolate behavior from it.
<InPhase>
peepsalot: Yeah, because you can't iterate over a 2.
<InPhase>
It's a meaningless statement.
<InPhase>
Python: for i in 2: print(i) --> 'int' object is not iterable
<InPhase>
Likewise for x = 2; print(*x)
<peepsalot>
hmm, yeah i suppose so. then again you have people arguing that len(123) should equal 1
<InPhase>
Let us agree to tell them no on that one. :)
<JordanBrown[m]>
but shouldn't len(123) be 3?
<JordanBrown[m]>
:-)
<InPhase>
The only lengths an integer has is byte count, bit count (storage or to the leftmost 1), and digit count in one or more representation.
<JordanBrown[m]>
$base=2; len(123)==7.
<JordanBrown[m]>
I am of course totally kidding.
<InPhase>
Good, at least we get an undef on that. I had to check.
<InPhase>
(And a warning.)
<InPhase>
I don't fault the "each" implementer as compatibility with concat was a reasonable choice at the introduction, but it'd probably be or would have been better to put some type consistency into the semantics of each.
<JordanBrown[m]>
I'm not sure which behavior of concat I would chose. "add this element to this list" is certainly a useful semantic... but so is "append this list to this list".
<InPhase>
Generally my support is present for adding in warnings at things that by all logic should be nonsense. Especially if they are still relatively new features.
<JordanBrown[m]>
Probably the "append this list" semantic, because you can easily implement "add this element" on top of it, and the inverse is not true.
GNUmoon has quit [Ping timeout: 258 seconds]
<InPhase>
JordanBrown[m]: Well you get both with explicitness. [each v1, each v2] or [e1, each v2] or [e1, e2]
<InPhase>
If you don't know what data you have, then you probably don't know what you're doing. ;)
<JordanBrown[m]>
Yes. concat() is completely unnecessary, completely replaceable by list comprehension.
<InPhase>
Although in the really rare case where you want to handle both data types, we have inspection checks like is_list
<JordanBrown[m]>
Not that I think it should be removed, or shouldn't have been included in the first place. concat() is a lot more obvious than list comprehension, handling simple cases simply, and there's a lot of value to that.