<InPhase>
I remember not finding that before, and then being told it was under summary. I just find that a very counterintuitive place to look so it keeps slipping away.
<InPhase>
I'm looking for details rather than a summary. :)
<InPhase>
I will try to lodge it deeper in the mind.
<peepsalot>
yep its a bit clunky i had to scour for it before as well
<peepsalot>
but yeah, as long as you ignore the mimalloc false warnings, there are none any more on our windows builds too. :D
<InPhase>
Sounds like great progress. :)
<InPhase>
Zero-warning builds are the way to go.
<InPhase>
Did you get that parser one that has been around forever?
<InPhase>
I looked at that one a bit ago, but I frankly don't understand it well enough to fix it.
<peepsalot>
%expect 3
<InPhase>
lol
<InPhase>
Ok.
<InPhase>
So the cheat mode. :)
<peepsalot>
:D
<InPhase>
I guess that's better than seeing the warning. I wish we knew how to properly fix it, but alas, for me that would require more deep diving into the structure of bison guts.
<peepsalot>
well iirc the problem was something like customizer dropdown with labels is indistinguishable from ranges, if a single option is there and the label and data are numbers
<InPhase>
Oh.
<InPhase>
Well that's sort of a design flaw then I guess.
<InPhase>
We should have used a different syntax, but now it's too late.
<peepsalot>
i don't remember which side the thing leans towards, but I also don't expect anyone to really do that. yeah and its basically Thingiverse' fault, i swear
<peepsalot>
er i mean actually the range is the only sensible interpretation and I think it happens to also resolve to that somehow
<peepsalot>
i don't know if that issue attribute to all 3 conflicts though. there is a way to make the parser spit out some examples of each type of conflict
<peepsalot>
InPhase: so you wanna do a code review on the PR?
<peepsalot>
the only thing left which I don't know about is how significant or serious those mac warnings are, but I assume its not a big deal since it passes tests *shrug*
<InPhase>
peepsalot: Yeah, working on it.
<InPhase>
I slowed down for the segments/slices validation. Looks correct.
<peepsalot>
oh yeah all the unsigned vs signed stuff. it is annoying that Qt uses signed return values for stuff like dropdown box indices etc
<InPhase>
Their obsession with signed is ridiculous, yeah.
<InPhase>
Also... "Avoid warning messages from boost which are also caused by boost's code" Appropriate snark detected. ;)
<InPhase>
I intended to post that here to let you know I started reviewing it, but accidentally posted it to the wrong channel. :)
tcurdt has quit [Ping timeout: 246 seconds]
<peepsalot>
lol
<peepsalot>
i'm convinced now that there's also something weird going on with how gcc is reporting those pragma messages, like it shows a seemingly unrelated include tree or something
<peepsalot>
makes it really hard to figure out what's actually triggering the message
<InPhase>
peepsalot: Clarification... why? using Geometry::transform; in Polygon2d Geometry, you picked up the transform that takes a Transform3d into the 2d one.
<InPhase>
(If I'm reading this right.)
<InPhase>
Looks like a semantic change.
<peepsalot>
that's the way to avoid warnings that transform(2d) is hiding the virtual function
<peepsalot>
i was asking about it to a mostly dead channel a couple days ago, https://bpa.st/QK6Q different class, same warning
<peepsalot>
InPhase: i used the solution suggest by that faq ^
<InPhase>
Yeah... But...
<InPhase>
The core problem is we're doing inheritance wrongly here.
<peepsalot>
maybe we could also just say = deleted or something?
<InPhase>
If a Geometry does 3D transforms, then a Polygon2d is not a Geometry.
<JordanBrown[m]>
peepsalot, InPhase: WRT that comment_parser warning, I think there's a clean way around it using precedence markers. But I'm not sure enough to say definitively.
<InPhase>
That's not an is-a relationship.
<peepsalot>
yeah i guess the base class should use a transform object that is dimension independent (pure virtual)?
<InPhase>
I'm getting sleepier, so I'll add a note here that this should be thought about, and plow forward and see how far I get.
<peepsalot>
ok sounds good, thanks for giving it a look
<JordanBrown[m]>
I'm up to *three* languages that let you define a subroutine without specifying a parameter list, plus assembly languages.
<JordanBrown[m]>
My bet is that most programmers have heard of one of them, but relatively few have heard of the other two.
<JordanBrown[m]>
(I've programmed in all three.)
<InPhase>
peepsalot: Done.
<peepsalot>
JordanBrown[m]: that sounds great if you figure it out. I didn't feel like fiddling too much with bison much, but if you guys would rather have that warning there as a reminder, I could be convinced to put it back.
<InPhase>
peepsalot: The purist in me would like it resolved on principle. But a bison guide I read encouraged only worrying about them if there is a risk of an exponentially growing cascade. I guess in this case you'd have to construct a very pathological nested customizer comment? Maybe?
<peepsalot>
you'd have to think it was a good idea to have a dropdown select box with one entry and the label is a number and the value behind the label is a number
<peepsalot>
then you'd have a problem
<peepsalot>
cause that looks like a range
<InPhase>
Well that alone isn't an issue, because it will pick whichever one is given the highest priority. (It just might not be the one you want.)
<InPhase>
But the reason there are warnings are because each shift/reduce conflict basically branches the parser into processing two parallel paths, and if you branch on a branch, and branch on each of those branches, and so on, then you get a lot of parallel bison parsing branches pretty quick.
<InPhase>
So the issue arises if there is a syntax where you leave it possible to do that.
<InPhase>
Where "parallel" is I believe processed sequentially, in a stepwise manner. But still, exponential branching of how many it iterates through at each step.
ur5us has joined #openscad
<JordanBrown[m]>
I'm not a parser guy, but I don't think it works like that. Rather, in the problem case it doesn't know which of those two paths to follow. At build time it picks one. At run time, that's the one it follows. Is that the one you expected it to follow? Maybe, maybe not.
<JordanBrown[m]>
Yacc is, I believe, limited to LALR(1) parsers. I believe Bison defaults to LALR(1) parsers. I don't know *exactly* what that means, but I think it means that it only looks ahead one token to figure out what construct it's looking at.
<JordanBrown[m]>
which has a couple of simple examples of non-LALR(1) grammars.
<JordanBrown[m]>
Though I don't think any of the examples that they give are unfixable. In the first example, slide 3, they give (on slide 5) a way to rearrange the grammar so that it accepts the desired inputs but is unambiguous.
_xxoxx has joined #openscad
<JordanBrown[m]>
Hmm. The post a few minutes ago against the "measurement tool" enhancement request gave me an idea.
Junxter has quit [Ping timeout: 272 seconds]
<JordanBrown[m]>
Suppose there was a module marker(str). That module adds a node to the CSG tree that stores that string.
Sauvin has quit [Ping timeout: 272 seconds]
<JordanBrown[m]>
For any given node in the CSG tree, it's possible to calculate where its origin is relative to the "world" space - you just multiply [0,0,0] by each of the transform matrixes above it in the tree.
Bocaneri has joined #openscad
Bocaneri is now known as Guest5006
<JordanBrown[m]>
So when the program is done, we have a list of N such marker nodes - perhaps with distinct names, perhaps not.
<JordanBrown[m]>
We could let the user pick any two markers, and we could tell them the "world" distance between those two markers.
<JordanBrown[m]>
Ugly as sin, but it might work.
<JordanBrown[m]>
(And if they don't have distinct names, well, that's the user's problem to solve.)
rumgzy has joined #openscad
Guest5006 has quit [Ping timeout: 272 seconds]
kanzure has quit [*.net *.split]
niyawe has quit [*.net *.split]
kanzure has joined #openscad
niyawe has joined #openscad
ur5us has quit [Read error: Connection reset by peer]
<buZz>
just to educate someone in #reprap on how i'd make a hex pattern
<J1A8494>
could have used HexGrid(es=10)circle(d=10); from my lib - Ü however hope that someone understood how you got that translations values calculated
<J1A8494>
i am using if(y%2) modulo for that
<J1A8494>
(for the 2 cases not the calculation of the translation)
ccox has quit [Remote host closed the connection]
ccox has joined #openscad
<J1A8494>
and as both cases are nearly identical i just would use translate([y%2?17.3205/2:0 + 17.3205*x ,y* …])
ccox has quit [Ping timeout: 276 seconds]
tcurdt has joined #openscad
KimK has quit [Read error: Connection reset by peer]
KimK has joined #openscad
<buZz>
i tried if (y%2) but didnt really seem to function well
<buZz>
no clue, probably did something wrong
<buZz>
but was mostly because that person always come in with some weird programmatic design idea/problem and then complains about blender
<buZz>
should just learn openscad already :D
__xxoxx has joined #openscad
_xxoxx has quit [Ping timeout: 272 seconds]
<J1A8494>
haha yeah absolutely
ccox has joined #openscad
ccox has quit [Ping timeout: 250 seconds]
teepee has quit [Ping timeout: 258 seconds]
hrberg has quit [Ping timeout: 246 seconds]
castaway has joined #openscad
ccox has joined #openscad
ccox has quit [Ping timeout: 250 seconds]
snaked has quit [Quit: Leaving]
teepee has joined #openscad
lastrodamo has joined #openscad
fling has quit [Remote host closed the connection]
fling has joined #openscad
<JordanBrown[m]>
Maybe we should have a formal governance body, a group with the authority (and responsibility) to say "yes" or "no" to proposals that affect the project.
<InPhase>
Teepee is our body. :)
<JordanBrown[m]>
Teepee has been doing a lot of that, but it does not seem appropriate to ask one person to make all of the decisions - and in particular to always be the bad guy.
<InPhase>
But if teepee ever decides he is growing weary, a group could be formed.
<JordanBrown[m]>
To be clear I do not mean to denigrate his work in any way.
<teepee>
oh, Michael is doing that on the forums, so there's a bit of sharing going on
<JordanBrown[m]>
I was thinking of a group of probably either three or five - an odd number for the usual voting reasons.
<teepee>
but I'm happy to grow that list of people
ccox has joined #openscad
<InPhase>
Generally we all agree on merits after talking things out anyway. But there could be some benefit in a few cases to having a clear decision people can see.
<JordanBrown[m]>
I would say that this hypothetical body would have authority over changes to the software, and over changes to the web site (and thus, e.g., over what is "official" in the way of mailing lists and forums, whatever "official" means).
<JordanBrown[m]>
Yes, the idea would be to have a way to formally make a decision.
<JordanBrown[m]>
Of course, any decision could be later revisited.
<teepee>
practically that's 3 people at this point (not counting kintel)
<teepee>
when talkling code / website as that's essentially github access currently
<JordanBrown[m]>
Without knowing names (other than teepee) I would suggest that the current people with write authorization to the repo be a "nominating committee" that nominates three or five people to serve as the governing body.
<JordanBrown[m]>
And I'll note that I am *not* one of those people, and am not angling for a position in that body. As the one proposing it, I'd actually prefer *not* to be in the initial slate. I don't want any hint that I'm making a power grab.
<teepee>
question would be if we are talking on technical side = github access + coding
<teepee>
or more general perspective, including power users / library authors
<InPhase>
I'd think that you wouldn't want a body of decision makers weighing in on every decision, but only stepping in to add clarity on disputes or vision questions. There is no need to centralize approval for typo fixes on the site, adding simple additional links, or uncontroversial code progression.
<JordanBrown[m]>
All stakeholders should be welcome.
<JordanBrown[m]>
Yes, agreed, the governing body could and should delegate its authority to one or more "gatekeepers" who would handle routine stuff on their own discretion.
<J1A8494>
teepocracy Ü
<JordanBrown[m]>
I mean, if teepee wants to be the BDFL then I suppose that's another approach, but dictatorships may seem ... undemocratic ... to some, and put a big burden on the dictator.
<teepee>
well, that's impossible anyway, that would have been (maybe still is of sorts) kintel
<InPhase>
I have zero issues with the way the project is going. But it is a theoretically interesting proposal to discuss because of the benefits of distributing blame in dispute resolution. :) It makes clearer that things are not personal, but in the interest of the project.
<JordanBrown[m]>
Right. We've had a couple of cases where some set of people thought that a particular proposal was a good idea, and some thought that it wasn't, and there isn't a clear path to resolving those questions.
epony has quit [Quit: QUIT]
<InPhase>
And it would all have to remain with a light touch favoring discussion anyway in most cases, as we know the apparent right decision shifts with time as we figure things out.
<InPhase>
But there are moments where everything has been said.
<JordanBrown[m]>
Right.
pa has quit [Ping timeout: 260 seconds]
<JordanBrown[m]>
And such a body would have a less formal role in general guidance. If several members say "we don't think we could ever accept a change like this", then that's a big hint, and is different from "we like the general idea but don't like this part".
pah has joined #openscad
<JordanBrown[m]>
I'd be happy to take a stab at writing a charter for such a thing, if people thought it worthwhile.
<JordanBrown[m]>
One unfortunate part is bootstrapping. There's no established decision-making body, so some set of people have to just assert that they are in control.
<JordanBrown[m]>
Marius would have to buy into it, because (if I'm reading the data right) he owns openscad.org.
<InPhase>
The decision making process seems clear. If it's to be done, teepee has to conclude it's a good idea and do it, as he is the active person sitting on all the github buttons. ;)
<J1A8494>
dictator what a bad wording .. it is called a Monarch or King
<Rayyan>
openscad ci takes a long time :P
<teepee>
not sure that's a much better word :)
<teepee>
Rayyan: it's running almost 2000 test cases, but yes it's not the fastest servers, but free without restrictions so it's still awesome
<InPhase>
I think kintel is basically in emeritus status, swinging by the office once in a while when the mac build breaks. Although we would all welcome him back out of OpenSCAD retirement.
<teepee>
circleci builds in less than 10 minutes
<teepee>
yep, what InPhase said, in some cases we have discussed stuff via email
<JordanBrown[m]>
But like I said, that puts a lot of responsibility on one person, and makes them be the bad guy all the time.
<J1A8494>
Captain .. as on pirate ships every body could challenge him also mutiny was an option .. so this wasn't legitimated by military or some bureaucracy - but by the staff
<JordanBrown[m]>
In open source, forking is always an option.
<InPhase>
Successful projects routinely transition away from BDFL type approaches at a certain scale and time. The only operative question is are we there yet.
<J1A8494>
apropos pirates we have a bountyhunter winner or?
<JordanBrown[m]>
The only "ship" that you have to take over is the name.
<InPhase>
Names are a dime a dozen. Open source communities are built as a consensus of people the same way.
<InPhase>
e.g. Libera vs Freenode.
<InPhase>
Hence why benevolence thrives.
<JordanBrown[m]>
Yes, new names are cheap, but names have value.
<JordanBrown[m]>
Right.
<JordanBrown[m]>
Whether it's a dictator or an oligarchy, the only thing they can "own" is the name.
<JordanBrown[m]>
"When in the course of human events, ..."
<JordanBrown[m]>
"We the Users of OpenSCAD, in order to form more perfect Software ..."
<InPhase>
Oof, I just read through this morning's PR vitriol.
<InPhase>
I don't like this tone existing on there.
<JordanBrown>
We just all spontaneously decided to hate him.
<JordanBrown>
Concur, not at all. Bad.
<InPhase>
I usually thank my coworkers when they remove my lines of code and get a cleaner result.
<JordanBrown>
It does depend on whether you agree that the result is cleaner.
<InPhase>
One of my first professional contributions to code involved getting a coworker to delete 2/3rds of his code by proposing a simpler design specification which turned out to be more flexible and general.
<InPhase>
He frowned, recognized it was right, and then went to do it.
<JordanBrown>
And in a healthy environment the worst that happens is that the original author is embarrassed that they didn't think of it first.
<JordanBrown>
Is Marius Developer Number One for OpenSCAD? Or was there somebody else before him?
<teepee>
not sure, no1 might have been Claire, but he was certainly around very near the beginning at Vienna Hacker Space (I believe)
<teepee>
and I'm also sure it would have not lived through without him keeping it alive around the 2012-2015 years
<InPhase>
JordanBrown: Claire worked alone for 6 months on it before kintel joined in, according to the git history.
<InPhase>
Then it was the two of them for a while.
<JordanBrown>
Right now I am characterizing Marius as "the most recently active of the original authors".
<JordanBrown>
and as "the formal owner of the openscad.org domain".
<InPhase>
Claire appears to have dropped out of working on OpenSCAD right before a few other programmers started contributing, so kintel ended up being the defacto community leader for the majority of a decade.
<InPhase>
So I think a fair way of looking at it is OpenSCAD was Claire's idea, vision, and initial implementation, and kintel built a community and led the morphing of it into the respected tool it became.
<JordanBrown>
The context is in appointing a bootstrapping committee to select the initial members of what I'm calling a steering commitee. Marius seems like a key participant in that process, both out of respect for his contribution and because AFAICT he is the formal owner of openscad.org.
<JordanBrown>
Where in the real world do OpenSCAD donations currently go? Is there a bank account, or do they go into somebody's personal account and are merely accounted separately?
<teepee>
Rayyan: yes, looking good
<teepee>
JordanBrown: all on OpenCollective now with I believe Marius and me as admins
<teepee>
he transfered all the earlier dontations (flattr, paypal, whatever else existed) there at some point
<JordanBrown>
Does that act as sort of a bank account, with mechanisms for disbursing money, e.g. to pay for network services?
<teepee>
I think it does, I have not tried yet
<JordanBrown>
Don't we have to pay for some of the build servers?
<teepee>
the older build server was donated by Don but it was not used much for a while and he dropped that maybe a year ago or so
<Virindi>
gosh, there's no need to turn things into a formal organization with rules documents. As soon as you do that, it is the beginning of the end, and people start playing politics and the organization itself turns into a monster which ruins things
<JordanBrown>
There are risks, for sure. But handling controversy requires some way to make decisions.
<Virindi>
when there is power, people use it and people seek it
<JordanBrown>
That power always exists. The question is whether it is in the open and has rules.
<Virindi>
except that creating a ruleset encourages everyone to think about things in that context, everyone is unconsciously gaming those rules
<teepee>
the file server is donated by Josh I believe
<JordanBrown>
Is that materially different from playing politics to cozy up to the people who hold the keys?
<teepee>
we only discussed getting a new server but that did not happen yet, would be much needed at this point I think
<Virindi>
soon enough, someone starts adding rules which have nothing to do with the project ;)
<JordanBrown>
Indeed, if the people in charge go sideways, you're in trouble. That's true whether they are a formal commitee, or merely the people who own the domain name or have github administrator authority.
<Virindi>
in my experience, the best project governance is to have a small channel of the handful of people who have contributed most to the project, and they just discuss what to do there and come to a consensus without any official rules
<JordanBrown>
What do you do when you cannot achieve unanimity?
<Virindi>
that's a problem in any organization.
<teepee>
well, that's what we have here mostly, just not as closed channel, people can watch things happen :)
<JordanBrown>
Although there are times and places for private conversation, in general I would think that any discussion and decision-making should take place in public.
<Virindi>
but by organizing it as a group of people who are friends and know each other, disputes are able to be resolved in a human manner rather than by yelling rules back and forth
<Virindi>
the human connection is the most important part
<JordanBrown>
And when that works, yes, that's best.
<JordanBrown>
But it doesn't always work.
<Virindi>
nothing "always works"
<JordanBrown>
And sometimes you just need a way to decide to end the discussion.
TheAssassin has quit [Remote host closed the connection]
GNUmoon has quit [Remote host closed the connection]
teepee has quit [Remote host closed the connection]
califax has quit [Remote host closed the connection]
fling has quit [Remote host closed the connection]
califax has joined #openscad
TheAssassin has joined #openscad
GNUmoon has joined #openscad
fling has joined #openscad
teepee has joined #openscad
fling has quit [Ping timeout: 258 seconds]
TheAssassin has quit [Ping timeout: 258 seconds]
TheAssassin has joined #openscad
fling has joined #openscad
jochen[m]1 has joined #openscad
_xxoxx has joined #openscad
__xxoxx has quit [Ping timeout: 272 seconds]
<teepee>
so talking of decisions :)
<teepee>
are there any objections regarding the object() PR? it's flagged experimental, so if we come up with a different name, that's fine to change later
<teepee>
but I tend to think it would be a way of collecting some actual usage feedback for the data structure stuff
<teepee>
it's lacking tests IIRC but we can add that later along with the literals maybe
<J1A8494>
as long you can switch it off .. why should there be any problem?
<Virindi>
why would you switch it off, just don't use it?
<Virindi>
if it is default on though, then it will end up in code and you will need it on
<teepee>
yes, that's the point of experimental, hinting that using it makes the script potentially not future proof
<teepee>
the switch makes it only a small concern, but if it would collide with currently ongoing feature discussions it would still not be a good idea to merge
<teepee>
but as I indicated, I don't see that to be the case
<Virindi>
cool :)
<Virindi>
one thing I would really, really like would be to have modules attached to objects (and also functions). it would be truly awesome to just be able to say, like,
<Virindi>
sidewall_screwtype.render();
<Virindi>
x = sidewall_screwtype.over_all_length();
<Virindi>
or
<Virindi>
I know, that kinda leads down the path of a can of worms because you'd want inheritance
<Virindi>
but jeez, it would be so much cleaner and easier.
<Virindi>
seems that you can almost do that with that PR
<Virindi>
you can construct objects with explicit, per-parameter inheritance
<Virindi>
but a module can't be assigned like a "function pointer", can it?
<Virindi>
foo = object(renderfunc=somemodule());
<Virindi>
you'd also need some concept of a this pointer :(
<InPhase>
teepee: I think the object() PR is the foundation of what should become a dict() PR.
<InPhase>
But there is still some debate on how that syntax should really work, or whether we should have some sort of comprehension form for that.
<InPhase>
But there seems to also be a dict PR I think.
<InPhase>
Generally I would say we're not ready to merge any of these because we don't want too many ways to do the same thing in the end, and we'll have to compare a few options.
<teepee>
so having a separate dictionary data type
<InPhase>
This set of stuff is probably the most impactful syntactical set of changes to the language probably for as long as I've seen it. Maybe in totality more impactful of a change than even function literals, because there are multiple types of such things being worked out at once.
<teepee>
with relaxed key rules
<teepee>
well, the object() function is not tied too much to the syntax topic or the implementation
<InPhase>
Yeah, I generally favor a data-only dict type with relaxed key rules and comprehensions support, plus an object literals type that exact matching to the other scope rules and includes geometry like normal scopes.
<teepee>
as long as access via dot notation and ["key"] works, the internal representation is not that critical, especially while it's experimental
<InPhase>
And that object() function looks like a dictionary to me, except called an object, and I'm not sure if that's the optimal syntax for it. Whatever syntax we have for dictionaries, we probably want to think about how comprehensions with them will look in combination with it.
<InPhase>
Like list definitions and list comprehensions look comfortably similar.
<teepee>
yes, in the future it would just be needed for calculated keys
<InPhase>
I think one of the most natural syntaxes for dictionaries in OpenSCAD will basically be a superset of JSON.
<InPhase>
Which would permit comprehensions analogous to the current list ones.
<InPhase>
But I haven't been mentally focusing on this part too much, since I think object literals is the harder problem to solve first. Dictionaries should be much simpler to add and sort out, as this can be pretty straightforward. As a data-only type there aren't a lot of complicated interactions, it's just a matter of picking a syntax that integrates comfortably.
<teepee>
question is if there's any reasonable syntax for calculated keys
<InPhase>
Because d={"foo":1, "bar":2}; echo(d["foo"]); So, d = {foo:1}; means that foo is parsed as a variable containing the key, and not the key.
<InPhase>
This has parity with Python, where it works intuitively.
<teepee>
hmm, that's certainly a useful point, following some existing stuff
<InPhase>
It then fits as a superset of JSON, with the "super" part being variables being allowed, and numerical keys being allowed.
<teepee>
might be challenging parser wise, but I guess that's a coding question which should follow the look from user/language side
<InPhase>
But in all cases with this, copy/paste of json would be a valid OpenSCAD dictionary.
<InPhase>
We get an edge over Python on that because our bools are the right case. ;)
<teepee>
:)
<J1A8494>
i get a bit headache as all changes make oscad more complex - so a beginner need knowledge about programming to understand this
<teepee>
you can still start with cube();
<J1A8494>
Ü
<InPhase>
When I taught OpenSCAD to non-programmers to make rockets, I taught a restricted subset. They learned very rapidly, making rockets on their 3rd class session working with it.
<InPhase>
It is natural that you need skill to parse complicated code written by an expert. But we're already well past that point.
<teepee>
and that's a good strategy in my view. allowing things to be simple while adding some more complex features for the power users
<J1A8494>
when i looked at funcutils i wondered "that is not oscad never seen this before"
<InPhase>
I'm already able to write OpenSCAD code that works that even I can barely understand if I take a break from it. ;)
<InPhase>
Ultimately, readability comes down to design choices.
<teepee>
and support for more powerful geometry features that we are currently lacking
<InPhase>
J1A8494: Well what we found when writing funcutils is that we could have written the vast majority of it without function literals. It was already possible for a long time.
<InPhase>
J1A8494: We just didn't think to do it, because we weren't motivated to use functions in such a complicated manner.
<J1A8494>
without literals you can't define a function within a function .. so this need to be a second function.
<InPhase>
I bet I could write a very similar abomination with a little reordering...
<InPhase>
I wonder how much reordering.
* InPhase
opens abomination.scad
<J1A8494>
btw 1,2,7,4,3 was the output if anyone wonders
<J1A8494>
and besides nobody should write code that way .. afaik this fup is not possible in scad
<teepee>
yeah, I don't think that would go through the parser
<teepee>
hmm, so having the object() PR while we sort out a syntax is not a good idea?
<teepee>
there's always the option to instead of removing the experimental flag to not have that
<teepee>
same tendency with roof() actually if we can get that merged with offset_extrude()
<InPhase>
teepee: I think merging it is premature, because I suspect we won't want it to look like that. But it might have a good chunk of the code we want.
<InPhase>
teepee: People get "used" to even the experimental features, so I think it's best if we have at least a reasonable expectation that it is the right direction before adding an experimental feature.
<teepee>
meaning syntax or behavior?
<teepee>
well, or both?
<InPhase>
Well syntax is the thing I think most needs tweaking there, but I'm concerned about the internal code mapping it to the object literals type as well, as I think that's probably not the right direction.
<InPhase>
I suspect we'll want a different internal type.
<InPhase>
(For dictionaries.)
<InPhase>
peepsalot correctly raised the point that it's best if echo produces a proper representation of creating the type, which is currently out of alignment for this, and will be forced to stay out of alignment if they have the same type.
<teepee>
hmm, I would not see that as a problem. it seems that the current data structure would just take over the dictionary type and we need a new one for the actual object stuff
pah has quit [Ping timeout: 272 seconds]
<teepee>
or to frame it as a question: would textmetrics() return the new object structure or a dictionary
<InPhase>
Well, I suppose that depends on whether or not we want to continue support . accesses of dictionary types.
<InPhase>
I'm not sold on the notion of whether or not that's a good idea.
<InPhase>
One way to access can be simpler.
<InPhase>
It means dictionaries have special members with a different access method, which could get awkwardly confusing given the variety.
<InPhase>
We special cased v.x and so on, but I think that was a fairly special case.
pah has joined #openscad
<teepee>
oh, so like dict.keys ?
<InPhase>
I just mean that we'd have dict.a1 and not dict.1a
<InPhase>
But it's also possible to consider a dict.keys if we forbid dotted access to a dictionary.
<teepee>
yes, that would need dict["1a"]
<InPhase>
So we open up more capability by not allowing it.
<teepee>
yeah, that sounds like a good idea
<InPhase>
Excessive flexibility can be disruptive. :)
<peepsalot>
my primary concern with objects is that I'd like to see comprehensions analogous to list comprehensions. the object() pr is not necessarily incompatible with that, but I think JordanBrown's OEP is. I mostly agree with other goals/aspects of the OEP though, so not sure what the best solution is.
<teepee>
I mainly wonder if it would be useful to get some feel for using this (without the geometry part)
<teepee>
even though a shorter and nicer syntax is certainly something I want :)
<InPhase>
peepsalot: I think these belong in a separate data-only dictionary type, at which point we can have both.
<JordanBrown[m]>
I still have to ask: what's the difference between an object and a dictionary?
<JordanBrown[m]>
So, ignoring syntax, one of them is a key-value list, and the other is a key-value list plus geometry.
<JordanBrown[m]>
No?
<InPhase>
JordanBrown[m]: One is a set of variables plus geometry, the other is a set of arbitrary key-values.
<InPhase>
JordanBrown[m]: Variables and keys are different sorts of things, as they can be different things.
<JordanBrown[m]>
How is that different from what I said?
<JordanBrown[m]>
Why isn't "variables" a strict subset of "keys"?
<InPhase>
It does happen to be a subset, yes.
<InPhase>
We have a Venn diagram of objects and dictionaries.
<InPhase>
But parts outside on each.
<peepsalot>
a key can be a string which is more flexible than variable name, but could also theoretically be any hashable type
<JordanBrown[m]>
As you've defined them, I think the only thing in "objects" that is outside of "dictionaries" is the geometry.
<InPhase>
JordanBrown[m]: But for example, it would be nice if we can write: for (k=d.keys)
<JordanBrown[m]>
Yes, I would probably start with strings only, but would treat non-strings as an error so that they could be first-class keys later.
<InPhase>
JordanBrown[m]: But we don't want to write o.keys, because we want to access any variable.
<JordanBrown[m]>
We don't say "for (v = array.entries)", do we?
<InPhase>
We can write for (k=d.keys) if we hold dictionary keys as "keys", and permit only d["foo"] or d[5] or d[mykeyvariable]
<JordanBrown[m]>
We say "for (v = array)".
<InPhase>
We might want d.items as well.
<JordanBrown[m]>
We should say "for (k = dict)" or "for (k = obj)".
<InPhase>
for (kv=d.items) { echo("key", kv[0], "value", kv[1]) (And later upgrading this with a previously proposed structured binding.)
<JordanBrown[m]>
(And, while I wouldn't call it a fait accompli, exactly that works today for the objects returned by textmetrics and import(json).)
<JordanBrown[m]>
for (k = d) echo("key", k, "value", d[k]);
<peepsalot>
btw, I looked at object implementation a while ago, and was wondering why an unordered_map + a vector is used to keep an ordering, instead of just a single (*not* unordered) map
<JordanBrown[m]>
I don't entirely remember. One aspect is that the memory manager wanted a vector.
<InPhase>
peepsalot: Faster lookup maybe.
<JordanBrown[m]>
I know that one of my considerations was that I found myself more comfortable with objects that maintained order than with ones that were random-order or alphabetical.
<JordanBrown[m]>
If I say { r: 100, g: 120, b:90 }, and then I echo it, I don't want to get {b: 90, g: 20, r: 100} or some random scramble.
<JordanBrown[m]>
Of course, it would be particularly bad if it said g:20 rather than g:120.
<peepsalot>
right, and a std::map can provide that
<peepsalot>
that's what unordered / (implied ordered) means
<JordanBrown[m]>
Entirely possible. Like I said, I don't remember why I had that second vector. Maybe it was just the way that I saw to maintain order, or maybe I just didn't know what tools were available.
<InPhase>
peepsalot: std::map sorts keys.
<InPhase>
Hmm. Also you can't sort mismatched types.
<InPhase>
Not sensibly anyway.
<InPhase>
We can however construct hashes for them and check equality I suppose.
<JordanBrown[m]>
Yeah, I was just looking at that. But I can easily believe that there's a different kind of map that is hashed for random access but maintains order for iteration.
<JordanBrown[m]>
Sure you can sort mismatched types.
<InPhase>
So the dict type certainly needs an unordered_map.
<Scopeuk>
std map is ordered , unorered map is hashed and potentially sparse (as the compiler may chose to store indexed by hash)
<JordanBrown[m]>
Bools sort first, then Numbers, then Strings.
<InPhase>
JordanBrown[m]: Well sure, but that's a little weird. Also I concur that a dictionary that preserves input order is best. Likewise an object literal with geometry should echo out in the same order things are defined.
<InPhase>
(I think.)
<JordanBrown[m]>
You mean sorting mismatched types? Sure. But since there's no clearly "right" way to do it, and you wouldn't expect people to do it routinely, as long as the behavior for any one type is sensible and the behavior for mixed types isn't stupid, you're OK.
<JordanBrown[m]>
But really I don't like the idea of object/dictionary members being sorted for iteration, regardless.
<InPhase>
If people end up using dictionaries to produce json output for external use, then we'll also want to respect their construction order just as for rgb.
<JordanBrown[m]>
Yes. I don't know if JSON is formally order-preserving, but practically it probably is.
<JordanBrown[m]>
It's not.
<JordanBrown[m]>
> An object is an unordered set of name/value pairs.
<InPhase>
{ "name1": ..., "bbox1": ..., "name2": ..., "bbox2": ...}; Someone probably ordered that on purpose. :)
<InPhase>
Yeah, json isn't guaranteed preserving with external tools, but you are allowed to order how you want.
<peepsalot>
hrm, maybe I was actually wrong about std::map. I thought there was a way to iterate over kvp in the order they were inserted
<peepsalot>
I think I must be mixing up memories of Java
<InPhase>
Python dictionaries are order preserving now, and it has been a huge asset since they got that in there.
teepee has quit [Ping timeout: 258 seconds]
teepee_ is now known as teepee
<JordanBrown[m]>
I believe that JavaScript objects are formally unordered and in practice usually order preserving.
<JordanBrown[m]>
I believe we have one component at work that relies on them being order preserving. Thankfully, however, it runs on a single unchanging JavaScript engine.
<JordanBrown[m]>
(Well, for a definition of "relies on" that is "we assume it's order preserving so that the UI comes out in the order we want it to".)
<JordanBrown[m]>
Anyhow, I believe that the two considerations for that second vector were (a) preserving order and (b) the interface with the memory manager.
<teepee>
haha, we had that with oracle sql query sorting order lately, breaking lots of stuff after a patch was applied
<JordanBrown[m]>
I can easily believe that there is a map variant that is order preserving, and I can easily believe that the interface with the memory manager could use some other construct. (Probably passing an iterator rather than passing a vector.)
<InPhase>
J1A8494: First-pass at reproducing the Java abomination from your image: https://bpa.st/QOQA
<InPhase>
J1A8494: I needed one function for the logic, and had to repeat a few calls in this approach.
<InPhase>
J1A8494: It's a little expanded because we can only pack those let calls into the expanding tree of ternary, rather than a more limited chain.
<JordanBrown[m]>
I am amused. I asked Mr. Google "C++ order preserving unordered map", which I admit is a bit of a contradiction, but its suggested questions include "What is the order of an unordered map" and "is unordered_map sorted in C++".
<J1A8494>
you created a function for the short circuits .. now you need to implement this into the oscad code
<JordanBrown[m]>
But the answer seems to be that there is no standard hashed insertion-order-producing map.
<InPhase>
Your search - "What is the order of an unordered map" - did not match any documents.
<InPhase>
I'm both surprised and pleased.
<InPhase>
But I suspect google might be broken. ;)
<JordanBrown[m]>
But anyhow, other than pulling in some external library, it seems like the options are unordered_map plus vector, and plus std::list.
<Scopeuk>
Internally, the elements are not sorted in any particular order, but organized into buckets. Which bucket an element is placed into depends entirely on the hash of its key. Keys with the same hash code appear in the same bucket.
<JordanBrown[m]>
Right. Iterates in essentially random order.
<JordanBrown[m]>
In hindsight, and ignoring the interaction with the memory manager, std::list might have been a better choice for order preserving than std::vector.
<InPhase>
JordanBrown[m]: vector is faster, and we don't have insert/remove.
<Scopeuk>
in fairness you could probably get good results with std::list of std::pair if you want something with fixed order and a data payload
<JordanBrown[m]>
I know that when Revar was doing object() he had some trouble with that vector, because when he was merging changes into an object he was having to insert and delete.
<InPhase>
Why not append?
<JordanBrown[m]>
I don't know enough implementation details, but I wouldn't be surprised if std::list performance is better than std::vector performance for these purposes.
<InPhase>
On large data it's very hard for std::list to beat std::vector.
<InPhase>
You need very specific circumstances that we aren't going to have.
<JordanBrown[m]>
I didn't look at the details. One problematic case is when you delete an entry; you kind of have to delete from the vector.
Bram[m]12 has joined #openscad
<peepsalot>
vector typically wins out due to cache locality
<InPhase>
Why would an entry be deleted in an immutable object?
<JordanBrown[m]>
I think it had to do with the object() operations that copy-and-modify.
<JordanBrown[m]>
object() can say "copy this object o1, add a new key k1, remove key k2, and merge in object o2".
<JordanBrown[m]>
So *while* you're doing the copy-and-modify it's updating.
<JordanBrown[m]>
I don't know why he would have needed to *insert*.
<InPhase>
Python has taught me to generate a new one with an exclusion, and then append new stuff.
<JordanBrown[m]>
What do you mean by "with an exclusion"?
<InPhase>
An iterate with an exclusion list.
<JordanBrown[m]>
OK, same concept.
<InPhase>
{k:v for k,v in d.items() if k%2 == 0}
<InPhase>
Something like that.
<JordanBrown[m]>
I don't remember exactly how the object() proposal looks, but I think that example I gave looks like
<J1A8494>
InPhase i think your code makes it even harder to guess what the output will be .. which probably had to do with the way the conditions are written
<InPhase>
Which in a hypothetical OpenSCAD comprehension with structured binding would look like: {for ([k,v]=d.items) if (k%2 == 0) k:v}
<JordanBrown[m]>
The biggest problem with object comprehensions is tied to the computable-key thing.
<JordanBrown[m]>
It really annoys me that in Python I have to put quotes around the keys.
<JordanBrown[m]>
I'm too used to JavaScript where I don't.
<InPhase>
I don't like pressing the key, but I appreciate the clarity between key and variable containing a key.
<JordanBrown[m]>
Come to think of it, a perhaps more obvious variant of that object() call would be
lastrodamo has quit [Quit: Leaving]
<InPhase>
s/pressing the key/pressing the quote key/
<JordanBrown[m]>
except that I don't remember where we came down on whether you could store an undef in an object, or if doing so deleted the key.
<InPhase>
JordanBrown[m]: Wait, is that the object merge syntax in that PR?
<JordanBrown[m]>
JavaScript has approximately four kinds of emptiness, and I think that's too many.
<JordanBrown[m]>
Yes.
<JordanBrown[m]>
Give or take that I am working from memory, rather than looking at what he actually implemented.
<InPhase>
Oh, distinguished by the lack of an assignment.
<JordanBrown[m]>
But it's a lot like that.
<JordanBrown[m]>
which is distinguished by the lack of an assignment?
<InPhase>
At first I thought it was blocking object nesting. But it's not.
<JordanBrown[m]>
There are, I think, three basic kinds of arguments that it allows:
<JordanBrown[m]>
object
<JordanBrown[m]>
key=value
<JordanBrown[m]>
[ [ "k1", "v1" ], ...]
<JordanBrown[m]>
and that latter allows ["k2"] with no value to delete an entry during the copy.
<JordanBrown[m]>
I don't remember whether he/we allowed the syntactic sugar of allowing a single-level array ["k1", "v1"] as a substitute for the two-level array.
<JordanBrown[m]>
The problem with that sugar is that you could conceivably interpret it as either setting k1 to v1, or as deleting k1 and v1.
<JordanBrown[m]>
Without the sugar, you need [["k1", "v1"]] and [["k2"]] if you want to add a single entry or remove a single entry.
<JordanBrown[m]>
Although I'd like to see an object comprehension syntax, I would be OK with using object() and list comprehension.
<JordanBrown[m]>
With numeric keys allowed, your example would be
<JordanBrown[m]>
object([ for (k=d) if (k%2 == 0) [ k, d[k] ] ])
<JordanBrown>
which is not quite as nice as your example, but isn't awful.
<JordanBrown>
I would *not* do the [k,v]=d.items part; I think that's trivially replaced by k=d and d[k], which doesn't require new syntax.
<JordanBrown>
But now I should go do some subtractive manufacturing with my saws.
ndnihil has quit [Quit: leaving]
ndnihil has joined #openscad
ndnihil has quit [Changing host]
ndnihil has joined #openscad
epony has joined #openscad
<InPhase>
JordanBrown[m]: I wouldn't special-case [k,v] for just dicts, but we've been thinking about that for a while like for ([x,y,z]=v)
<InPhase>
Where v would be a vector of points.
<InPhase>
C++ and Python both support this now. It seems to be all the rage, and just makes things a bit more elegant to give them names instead of trying to track index numbers.
<InPhase>
I do find it easy to make mistakes when I get to things that look like a(p[0][2], p[1][2], p[2][2]) + b(p[0][1], p[1][1], p[2][1]). I couldn't even type this example without making and correcting 4 typos. ;)
rawgreaze has quit [Read error: Connection reset by peer]
castaway has quit [Ping timeout: 250 seconds]
<JordanBrown[m]>
Well, yeah, but we already have the .x .y .z magic for arrays.
<JordanBrown[m]>
And why did you have your arrays transposed from the obvious ways? And why did your functions take x,y,z instead of a vec3?
<JordanBrown[m]>
To a certain extent I'm just playing with you, but at the same time your example would have been a lot simpler if designed a little differently.
<JordanBrown[m]>
a(p[2]) + b(p[1])
<teepee>
joseph_: don't forget the submission deadline...
<InPhase>
JordanBrown[m]: It was a haphazard example similar to things I've stumbled on before.
<JordanBrown>
Sure, but do we need more helpful tools when the programmer already doesn't use the ones available?
<teepee>
true, but it's an example, maybe it would need to set Z of p[1] to 0
<JordanBrown>
There are definitely cases where what JavaScript calls a destructuring assignment would be useful. (Fewer, once you can use objects/dictionaries and so names instead of indexes when passing around structured data.)
<JordanBrown>
But I have to worry that we are in danger of building a language that has so many clever little things that only experts will ever use, that the size and complexity of the documentation will scare beginners off.
<joseph_>
teepee: I just uploaded my final report in the form of a comment on my PR. Please let me know when you've had a chance to review it. We previously talked about me finalizing and uploading it few weeks ago. However, shortly after that I was sick with some kind of cold/flu and fell behind on coursework. I'm still busy catching up, but I know the report is now due in just over 24hrs.
<InPhase>
joseph_: Make sure you know the submission time in the correct timezone.
<InPhase>
joseph_: People get bitten by that every year.
<teepee>
yeah, regardless of everything, I'd suggest to submit the report today, things on the last day could be shaky
<teepee>
with today meaning oct, 23th which already started here :)
<JordanBrown[m]>
UTC all the way
<joseph_>
teepee InPhase: I've confirmed that it's Oct 23rd 11pm CDT. However, I agree with the suggestion to submit now as a precaution. I'm about to fill out the Google form using the link to my PR
<teepee>
yes, I think google says deadline is 18:00 UTC @ oct 24th
<teepee>
but there have been issues with timezone handling of the web app before
<JordanBrown[m]>
MS Exchange meeting messages don't have TZs marked on them. They *are* converted to your local TZ, which is nice, but they don't *say* that they've done that. And since I basically never have a scheduled meeting where all of the participants are in the same TZ...
<teepee>
usually you can update the forms till deadline
<joseph_>
teepee: It seems to be confusing because previous ones were 18:00 UTC. But now it seems to be 04:00 UTC Oct 24th. Perhaps this is because of the extension. Anyway, I believe the dashboard will show you the deadline for your official review of my report (I don't see it currently). Yours may be 04:00 UTC on the deadline day as well
<teepee>
yeah, we have that for 2 x for 2 weeks each year with meetings between us and germany
<teepee>
hmm, right, I'm getting Deadline: October 24, 2022 6:00 AM
<teepee>
what an odd choise, that's 4 AM UTC I think
<teepee>
so same point in time confirmed
<teepee>
actual selection sounds like a typo as the timeline has September 5 - September 12 - 18:00 UTC for the normal length project
<teepee>
hence the "submit one day earlier" rule :)
<teepee>
well, recommendation
<teepee>
that somehow looks like combining 2 bugs: mixing up AM and PM and also local time vs. UTC
<teepee>
brb, need to get headphones :) such great dj sets dropping lately, I really would like to have a week off and just have those running all the time :)
_xxoxx has quit [Quit: Leaving]
<joseph_>
teepee: Just submitted my portion of the final report. It looks like the deadline for your final review is Oct 31 4:00 am UTC (although it shows in my local time which is Oct 30th)