discuss@lists.openscad.org

OpenSCAD general discussion Mailing-list

View all threads

Classes (types) for OpenSCAD?

B
ben
Mon, Jul 23, 2018 4:29 AM

Hello OpenSCAD community!  :)

When using OpenSCAD, I find myself missing things from other standard
languages:

  • The ability to throw exceptions, and be informed where in the code the
    exception occurred (like a stack trace)
  • Modularity: the ability to tie things together (data for sure, but also
    functions) in objects.
  • Type safety, a compiler or type checker could prevent me from making lots
    of mistakes.

I wrote some stuff (https://github.com/ben-horner/scad-primitives), and was
planning to try to get run-time type checking into OpenSCAD.  It includes:

  • Hacky way of throwing exceptions (using infinite recursion) which echos a
    string which you can search for in the source.
  • Full featured map (aka dictionary) functionality (can't speak to
    performance...) through global functions.

I've iterated a few times using (nested) maps to define the data members of
objects, and tried to get type checking working, but what I have to work
with seems too thin.  I've started writing some Scala code, which could turn
into a DSL (domain specific language) which compiles to OpenSCAD for
rendering.

My question(s) are:

  • Are there other things out there that can give me some of what I want
    already?

  • Development complexity versus performance:  If I continue down my current
    path, would it be necessary to support all of OpenSCAD's current syntax?
    i.e. "intersect_for()"?  I could build code which produces an
    intersect_for() statement, but I could also write code which produces one
    big "intersect()" with all of the intersected elements explicitly present.
    Could there be a render-time benefit to keeping things more concise with
    intersect_for()?  There are many other cases where if you were writing in
    OpenSCAD you'd want to write for reuse (modules and functions), but is there
    any performance benefit to doing it that way?  It would be easier to write
    my Scala code to just write sprawling huge OpenSCAD files, is there a
    downside to this?

--
Sent from: http://forum.openscad.org/

Hello OpenSCAD community! :) When using OpenSCAD, I find myself missing things from other standard languages: * The ability to throw exceptions, and be informed where in the code the exception occurred (like a stack trace) * Modularity: the ability to tie things together (data for sure, but also functions) in objects. * Type safety, a compiler or type checker could prevent me from making lots of mistakes. I wrote some stuff (https://github.com/ben-horner/scad-primitives), and was planning to try to get run-time type checking into OpenSCAD. It includes: * Hacky way of throwing exceptions (using infinite recursion) which echos a string which you can search for in the source. * Full featured map (aka dictionary) functionality (can't speak to performance...) through global functions. I've iterated a few times using (nested) maps to define the data members of objects, and tried to get type checking working, but what I have to work with seems too thin. I've started writing some Scala code, which could turn into a DSL (domain specific language) which compiles to OpenSCAD for rendering. My question(s) are: * Are there other things out there that can give me some of what I want already? * Development complexity versus performance: If I continue down my current path, would it be necessary to support all of OpenSCAD's current syntax? i.e. "intersect_for()"? I could build code which produces an intersect_for() statement, but I could also write code which produces one big "intersect()" with all of the intersected elements explicitly present. Could there be a render-time benefit to keeping things more concise with intersect_for()? There are many other cases where if you were writing in OpenSCAD you'd want to write for reuse (modules and functions), but is there any performance benefit to doing it that way? It would be easier to write my Scala code to just write sprawling huge OpenSCAD files, is there a downside to this? -- Sent from: http://forum.openscad.org/
R
runsun
Sat, Jul 28, 2018 12:03 AM

The following are parts of my lib Scadx :
https://bitbucket.org/runsun/scadx/src/master/

Full featured map (aka dictionary) functionality (can't speak to

performance...) through global functions.

A hash based on search() could be very efficient:
https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md#hash

This hash is heavily used though out the entire lib. For more hash-related
functions, see:
https://bitbucket.org/runsun/scadx/src/master/scadx_hash.scad

Type safety, a compiler or type checker could prevent me from making
lots

of mistakes

A lot of type-checking functions (including geometric type like point etc):
https://bitbucket.org/runsun/scadx/src/master/scadx_inspect.scad

The ability to throw exceptions, and be informed where in the code the

exception occurred (like a stack trace)

I haven't visited this file for a long time:
https://bitbucket.org/runsun/scadx/src/master/scadx_error.scad

The stack tracing doesn't seem to be possible in OpenSCAD. But, a
tree-structure logging system might help:
https://bitbucket.org/runsun/scadx/src/master/scadx_log.scad
Check this out for demo:
https://bitbucket.org/runsun/scadx/src/master/demos/demo_log.scad

Also check these for your other interests:
https://bitbucket.org/runsun/scadx/src/master/scadx_array.scad
https://bitbucket.org/runsun/scadx/src/master/scadx_range.scad

Modularity: the ability to tie things together (data for sure, but also

functions) in objects.

I've tried to construct some data structures to represent objects, packed
with all object properties and steps required to move/modify it, then use a
Make(data) module to draw it. The packaging makes it feel like
a class in OOP obj and allows it to be passed around, but since everything
is packed, it's extremely difficult to debug. The codes are still there:
https://bitbucket.org/runsun/scadx/src/master/scadx_make.scad
but I've walked away from it.

I do applied some data "packaging" (in a hash) to represent func/mod
arguments. This allow users to design a mod:

module Mymod( len,w, opt ) { ... }

then use it anyway like:

Mymod( len=3, w=4 );
Mymod( opt=["len", 3, "w",4] );
Mymod( w=5, opt=["len", 3, "w",4] ); // 5 would replace 4

and the opt can be passed around and updated at RT:

Mymod1( opt );
Mymod2( w=8, opt );
Mymod3( len=10, opt );

It also allows users to set/modify the properties of a sub-unit of an
object:

module Arm( len, d, opt ) { ... };
Arm( len=10, d=1 );

module Body( leg, arm, opt ) { ... } ;
Body( arm = arm_opt ); // where arm_opt = ["len",10, "d",1]

In this case, you can't do Arm( len=10, d=1) any more because Arm is inside
the Body.

The code :
https://bitbucket.org/runsun/scadx/src/master/scadx_args.scad


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

The following are parts of my lib Scadx : https://bitbucket.org/runsun/scadx/src/master/ >>> Full featured map (aka dictionary) functionality (can't speak to performance...) through global functions. A hash based on search() could be very efficient: https://github.com/runsun/OpenSCAD_Tips/blob/master/snippets.md#hash This hash is heavily used though out the entire lib. For more hash-related functions, see: https://bitbucket.org/runsun/scadx/src/master/scadx_hash.scad >>> Type safety, a compiler or type checker could prevent me from making >>> lots of mistakes A lot of type-checking functions (including geometric type like point etc): https://bitbucket.org/runsun/scadx/src/master/scadx_inspect.scad >>> The ability to throw exceptions, and be informed where in the code the exception occurred (like a stack trace) I haven't visited this file for a long time: https://bitbucket.org/runsun/scadx/src/master/scadx_error.scad The stack tracing doesn't seem to be possible in OpenSCAD. But, a tree-structure logging system might help: https://bitbucket.org/runsun/scadx/src/master/scadx_log.scad Check this out for demo: https://bitbucket.org/runsun/scadx/src/master/demos/demo_log.scad Also check these for your other interests: https://bitbucket.org/runsun/scadx/src/master/scadx_array.scad https://bitbucket.org/runsun/scadx/src/master/scadx_range.scad >>> Modularity: the ability to tie things together (data for sure, but also functions) in objects. I've tried to construct some data structures to represent objects, packed with all object properties and steps required to move/modify it, then use a Make(data) module to draw it. The packaging makes it feel like a class in OOP obj and allows it to be passed around, but since everything is packed, it's extremely difficult to debug. The codes are still there: https://bitbucket.org/runsun/scadx/src/master/scadx_make.scad but I've walked away from it. I do applied some data "packaging" (in a hash) to represent func/mod arguments. This allow users to design a mod: module Mymod( len,w, opt ) { ... } then use it anyway like: Mymod( len=3, w=4 ); Mymod( opt=["len", 3, "w",4] ); Mymod( w=5, opt=["len", 3, "w",4] ); // 5 would replace 4 and the opt can be passed around and updated at RT: Mymod1( opt ); Mymod2( w=8, opt ); Mymod3( len=10, opt ); It also allows users to set/modify the properties of a sub-unit of an object: module Arm( len, d, opt ) { ... }; Arm( len=10, d=1 ); module Body( leg, arm, opt ) { ... } ; Body( arm = arm_opt ); // where arm_opt = ["len",10, "d",1] In this case, you can't do Arm( len=10, d=1) any more because Arm is inside the Body. The code : https://bitbucket.org/runsun/scadx/src/master/scadx_args.scad ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer ); $ Tips ; $ Snippets -- Sent from: http://forum.openscad.org/
R
runsun
Sat, Jul 28, 2018 12:30 AM

runsun wrote

The logging system in action:
http://forum.openscad.org/file/t602/2018-07-27_19_25_46-Planter_Bench_187q.png


$  Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText  ( OpenSCAD lexer ); $ Tips ; $ Snippets

--
Sent from: http://forum.openscad.org/

runsun wrote > tree-structure logging system might help: > https://bitbucket.org/runsun/scadx/src/master/scadx_log.scad > Check this out for demo: > https://bitbucket.org/runsun/scadx/src/master/demos/demo_log.scad The logging system in action: <http://forum.openscad.org/file/t602/2018-07-27_19_25_46-Planter_Bench_187q.png> ----- $ Runsun Pan, PhD $ libs: scadx , doctest , faces ( git ), offline doc ( git ), runscad.py ( 2 , git ), editor of choice: CudaText ( OpenSCAD lexer );&nbsp;$ Tips ;&nbsp;$ Snippets -- Sent from: http://forum.openscad.org/
BH
Benjamin Hill
Sat, Jul 28, 2018 12:39 AM

Heretical question: why not use JavaScript/ES6 with an import of OpenSCAD
functions?

import { scad } from '/modules/openscad.js';
[1,5,7,8]
.filter(x => x>2)
.forEach(x => {
scad.translate(x, x*100, 0);
scad.circle(x);
});

On Sun, Jul 22, 2018 at 9:30 PM ben ben.k.horner@gmail.com wrote:

Hello OpenSCAD community!  :)

When using OpenSCAD, I find myself missing things from other standard
languages:

  • The ability to throw exceptions, and be informed where in the code the
    exception occurred (like a stack trace)
  • Modularity: the ability to tie things together (data for sure, but also
    functions) in objects.
  • Type safety, a compiler or type checker could prevent me from making lots
    of mistakes.

I wrote some stuff (https://github.com/ben-horner/scad-primitives), and
was
planning to try to get run-time type checking into OpenSCAD.  It includes:

  • Hacky way of throwing exceptions (using infinite recursion) which echos a
    string which you can search for in the source.
  • Full featured map (aka dictionary) functionality (can't speak to
    performance...) through global functions.

I've iterated a few times using (nested) maps to define the data members of
objects, and tried to get type checking working, but what I have to work
with seems too thin.  I've started writing some Scala code, which could
turn
into a DSL (domain specific language) which compiles to OpenSCAD for
rendering.

My question(s) are:

  • Are there other things out there that can give me some of what I want
    already?

  • Development complexity versus performance:  If I continue down my current
    path, would it be necessary to support all of OpenSCAD's current syntax?
    i.e. "intersect_for()"?  I could build code which produces an
    intersect_for() statement, but I could also write code which produces one
    big "intersect()" with all of the intersected elements explicitly present.
    Could there be a render-time benefit to keeping things more concise with
    intersect_for()?  There are many other cases where if you were writing in
    OpenSCAD you'd want to write for reuse (modules and functions), but is
    there
    any performance benefit to doing it that way?  It would be easier to write
    my Scala code to just write sprawling huge OpenSCAD files, is there a
    downside to this?

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

Heretical question: why not use JavaScript/ES6 with an import of OpenSCAD functions? import { scad } from '/modules/openscad.js'; [1,5,7,8] .filter(x => x>2) .forEach(x => { scad.translate(x, x*100, 0); scad.circle(x); }); On Sun, Jul 22, 2018 at 9:30 PM ben <ben.k.horner@gmail.com> wrote: > Hello OpenSCAD community! :) > > When using OpenSCAD, I find myself missing things from other standard > languages: > * The ability to throw exceptions, and be informed where in the code the > exception occurred (like a stack trace) > * Modularity: the ability to tie things together (data for sure, but also > functions) in objects. > * Type safety, a compiler or type checker could prevent me from making lots > of mistakes. > > I wrote some stuff (https://github.com/ben-horner/scad-primitives), and > was > planning to try to get run-time type checking into OpenSCAD. It includes: > * Hacky way of throwing exceptions (using infinite recursion) which echos a > string which you can search for in the source. > * Full featured map (aka dictionary) functionality (can't speak to > performance...) through global functions. > > I've iterated a few times using (nested) maps to define the data members of > objects, and tried to get type checking working, but what I have to work > with seems too thin. I've started writing some Scala code, which could > turn > into a DSL (domain specific language) which compiles to OpenSCAD for > rendering. > > My question(s) are: > * Are there other things out there that can give me some of what I want > already? > > * Development complexity versus performance: If I continue down my current > path, would it be necessary to support all of OpenSCAD's current syntax? > i.e. "intersect_for()"? I could build code which produces an > intersect_for() statement, but I could also write code which produces one > big "intersect()" with all of the intersected elements explicitly present. > Could there be a render-time benefit to keeping things more concise with > intersect_for()? There are many other cases where if you were writing in > OpenSCAD you'd want to write for reuse (modules and functions), but is > there > any performance benefit to doing it that way? It would be easier to write > my Scala code to just write sprawling huge OpenSCAD files, is there a > downside to this? > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
N
NateTG
Sat, Jul 28, 2018 5:36 AM

Heretical question: why not use JavaScript/ES6 with an import of OpenSCAD

functions?

I've been musing on writing an OpenSCAD interpreter for blender since it
seems to have a more suitable interaction with the geometry engine than
OpenSCAD does.

--
Sent from: http://forum.openscad.org/

> Heretical question: why not use JavaScript/ES6 with an import of OpenSCAD functions? I've been musing on writing an OpenSCAD interpreter for blender since it seems to have a more suitable interaction with the geometry engine than OpenSCAD does. -- Sent from: http://forum.openscad.org/
DM
doug moen
Mon, Jul 30, 2018 11:52 PM

I think your approach to create a  DSL in Scala is a good one.
You can't get very far by trying to "fix" OpenSCAD using libraries.
There are too many limitations in the language.

If I were you, I would try to use the smallest possible subset of OpenSCAD
for your code generator. The language is full of weird, inconvenient
behaviour,
and this minimizes the pain of dealing with the mismatch between Scala and
OpenSCAD semantics.

Do not output variable definitions, function definitions, module
definitions,
if statements, or for statements. Do all of this in Scala code, and just
output
nested calls to primitive modules like cube, union, etc.

If you are worried about performance, try measuring it. My guess is that
it will be fine. The OpenSCAD interpreter is slow, so by doing as much
computation
as possible in Scala, you will more likely be speeding things up.

You are reinventing the wheel -- SolidPython is occasionally mentioned on
the list,
and probably already does what you want, if you are okay with using Python.
But that's okay, because building these kinds of systems is fun.

On 23 July 2018 at 00:29, ben ben.k.horner@gmail.com wrote:

Hello OpenSCAD community!  :)

When using OpenSCAD, I find myself missing things from other standard
languages:

  • The ability to throw exceptions, and be informed where in the code the
    exception occurred (like a stack trace)
  • Modularity: the ability to tie things together (data for sure, but also
    functions) in objects.
  • Type safety, a compiler or type checker could prevent me from making lots
    of mistakes.

I wrote some stuff (https://github.com/ben-horner/scad-primitives), and
was
planning to try to get run-time type checking into OpenSCAD.  It includes:

  • Hacky way of throwing exceptions (using infinite recursion) which echos a
    string which you can search for in the source.
  • Full featured map (aka dictionary) functionality (can't speak to
    performance...) through global functions.

I've iterated a few times using (nested) maps to define the data members of
objects, and tried to get type checking working, but what I have to work
with seems too thin.  I've started writing some Scala code, which could
turn
into a DSL (domain specific language) which compiles to OpenSCAD for
rendering.

My question(s) are:

  • Are there other things out there that can give me some of what I want
    already?

  • Development complexity versus performance:  If I continue down my current
    path, would it be necessary to support all of OpenSCAD's current syntax?
    i.e. "intersect_for()"?  I could build code which produces an
    intersect_for() statement, but I could also write code which produces one
    big "intersect()" with all of the intersected elements explicitly present.
    Could there be a render-time benefit to keeping things more concise with
    intersect_for()?  There are many other cases where if you were writing in
    OpenSCAD you'd want to write for reuse (modules and functions), but is
    there
    any performance benefit to doing it that way?  It would be easier to write
    my Scala code to just write sprawling huge OpenSCAD files, is there a
    downside to this?

--
Sent from: http://forum.openscad.org/


OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org

I think your approach to create a DSL in Scala is a good one. You can't get very far by trying to "fix" OpenSCAD using libraries. There are too many limitations in the language. If I were you, I would try to use the smallest possible subset of OpenSCAD for your code generator. The language is full of weird, inconvenient behaviour, and this minimizes the pain of dealing with the mismatch between Scala and OpenSCAD semantics. Do not output variable definitions, function definitions, module definitions, if statements, or for statements. Do all of this in Scala code, and just output nested calls to primitive modules like cube, union, etc. If you are worried about performance, try measuring it. My guess is that it will be fine. The OpenSCAD interpreter is slow, so by doing as much computation as possible in Scala, you will more likely be speeding things up. You are reinventing the wheel -- SolidPython is occasionally mentioned on the list, and probably already does what you want, if you are okay with using Python. But that's okay, because building these kinds of systems is fun. On 23 July 2018 at 00:29, ben <ben.k.horner@gmail.com> wrote: > Hello OpenSCAD community! :) > > When using OpenSCAD, I find myself missing things from other standard > languages: > * The ability to throw exceptions, and be informed where in the code the > exception occurred (like a stack trace) > * Modularity: the ability to tie things together (data for sure, but also > functions) in objects. > * Type safety, a compiler or type checker could prevent me from making lots > of mistakes. > > I wrote some stuff (https://github.com/ben-horner/scad-primitives), and > was > planning to try to get run-time type checking into OpenSCAD. It includes: > * Hacky way of throwing exceptions (using infinite recursion) which echos a > string which you can search for in the source. > * Full featured map (aka dictionary) functionality (can't speak to > performance...) through global functions. > > I've iterated a few times using (nested) maps to define the data members of > objects, and tried to get type checking working, but what I have to work > with seems too thin. I've started writing some Scala code, which could > turn > into a DSL (domain specific language) which compiles to OpenSCAD for > rendering. > > My question(s) are: > * Are there other things out there that can give me some of what I want > already? > > * Development complexity versus performance: If I continue down my current > path, would it be necessary to support all of OpenSCAD's current syntax? > i.e. "intersect_for()"? I could build code which produces an > intersect_for() statement, but I could also write code which produces one > big "intersect()" with all of the intersected elements explicitly present. > Could there be a render-time benefit to keeping things more concise with > intersect_for()? There are many other cases where if you were writing in > OpenSCAD you'd want to write for reuse (modules and functions), but is > there > any performance benefit to doing it that way? It would be easier to write > my Scala code to just write sprawling huge OpenSCAD files, is there a > downside to this? > > > > -- > Sent from: http://forum.openscad.org/ > > _______________________________________________ > OpenSCAD mailing list > Discuss@lists.openscad.org > http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org >
TP
Torsten Paul
Tue, Jul 31, 2018 12:31 AM

On 07/31/2018 01:52 AM, doug moen wrote:

There are too many limitations in the language.

Or just another crazy thought...

Help improving OpenSCAD itself

Some features that are mentioned in the initial post
are already implemented, like assert().

ciao,
Torsten.

On 07/31/2018 01:52 AM, doug moen wrote: > There are too many limitations in the language. > Or just another crazy thought... > Help improving OpenSCAD itself Some features that are mentioned in the initial post are already implemented, like assert(). ciao, Torsten.
B
ben
Wed, Aug 1, 2018 5:33 AM

I don't know if it's heretical, but I wouldn't be able to lean on the
language for type checking right?
I'd have to implement type checking myself, like I tried to in pure
OpenSCAD.

Were you describing a javascript library that already exists?

--
Sent from: http://forum.openscad.org/

I don't know if it's heretical, but I wouldn't be able to lean on the language for type checking right? I'd have to implement type checking myself, like I tried to in pure OpenSCAD. Were you describing a javascript library that already exists? -- Sent from: http://forum.openscad.org/
B
ben
Wed, Aug 1, 2018 5:51 AM

I got the version with assert on my Mac, but it died, now on my linux box I
think it wasn't available.  I did like having it though.

I thought that trying to make a large change to a program that people depend
on would take a lot of bullet-proofing, and corner-case coverage than
writing something separate.  I guess I could check out the actual OpenSCAD
code to see about adding a type system, do you really think that's a good
path to take?

--
Sent from: http://forum.openscad.org/

I got the version with assert on my Mac, but it died, now on my linux box I think it wasn't available. I did like having it though. I thought that trying to make a large change to a program that people depend on would take a lot of bullet-proofing, and corner-case coverage than writing something separate. I guess I could check out the actual OpenSCAD code to see about adding a type system, do you really think that's a good path to take? -- Sent from: http://forum.openscad.org/
B
ben
Wed, Aug 1, 2018 5:57 AM

I just looked at SolidPython a bit, and will look some more.  (Seeing the
word 'right' used for positive X made me think there could be lots of stuff
I didn't like in there.)  Being based on python would mean no static type
safety right?

--
Sent from: http://forum.openscad.org/

I just looked at SolidPython a bit, and will look some more. (Seeing the word 'right' used for positive X made me think there could be lots of stuff I didn't like in there.) Being based on python would mean no static type safety right? -- Sent from: http://forum.openscad.org/