EmbeddedRelated.com
Forums

Language feature selection

Started by Don Y March 5, 2017
On 2017-03-05, Don Y <blockedofcourse@foo.invalid> wrote:
> A quick/informal/UNSCIENTIFIC poll: > > What *single* (non-traditional) language feature
What's the definition of "non-traditional"? -- Grant Edwards grant.b.edwards Yow! My haircut is totally at traditional! gmail.com
On 3/6/2017 11:59 AM, Grant Edwards wrote:
> On 2017-03-05, Don Y <blockedofcourse@foo.invalid> wrote: >> A quick/informal/UNSCIENTIFIC poll: >> >> What *single* (non-traditional) language feature > > What's the definition of "non-traditional"?
Whatever you want ("unscientific"). The question is meant to draw attention to that aspect of <your_ideal_language> that you consider to be most valuable (using *your* definition of "valuable").
On 3/6/2017 10:27 AM, Tom Gardner wrote:
> On 06/03/17 15:39, Don Y wrote: >> On 3/6/2017 1:39 AM, Tom Gardner wrote: >>> On 05/03/17 23:03, Don Y wrote: >>>> A quick/informal/UNSCIENTIFIC poll: >>>> >>>> What *single* (non-traditional) language feature do you find most >>>> valuable in developing code? (and, applicable language if unique >>>> to *a* language or class of languages) >>> >>> Understandabililty, of the language and of programs >>> written in that language. >> >> Isn't that dependant on the characteristics of the language >> and how its applied? E.g., APL is as understandable as COBOL... >> >> Do you count syntactic complexity as contradicting that goal? >> Or, enhancing it? >> >> E.g., is C's trinary operator an *improvement* or *detriment* >> (over a move explicit use of conditionals) to "understandability"? >> Does Limbo's combination of "declare and define" syntax (as >> an alternative to independent declarations and definitions) >> improve understandability? How does "terseness" factor into >> that calculus (as an aid or detriment)? > > Simplicity aids understanding.
But simplicity and complexity can exist in the same operation! E.g., the "copy operator" in C++ can do a shitload of work embracing a bunch of complex relationships "under the covers" but all intended to make the NET operation "simple": NewPlanet = Earth
> If complexity leads to simpler programs, then it is > acceptable. But usually complexity will end up being > poorly used. Hence I prefer simplicity.
How does having N different ways of "doing the same thing" factor into simplicity/understanding? If I parallel load "zeroes" into a counter INSTEAD of "clearing" it, have I made things more complex ("Why the hell is he loading zeroes instead of just clearing the damn thing?")
> Terseness helps, when not taken to extremes. > Verbosity helps, when not taken to extremes. > Good taste is important.
So, a language should support terseness AND verbosity? :> [I guess this begs another question regarding who/what you "hold responsible" -- the language (for enabling bad practices) or the developer (for employing them)!]
> Being explicit and unambiguous is very important; > artifacts that worsen those are to be deprecated.
What if that drives verbosity up?
On 06/03/17 16:47, Don Y wrote:
> On 3/6/2017 12:40 AM, David Brown wrote: >> On 06/03/17 00:03, Don Y wrote: >>> A quick/informal/UNSCIENTIFIC poll: >>> >>> What *single* (non-traditional) language feature do you find most >>> valuable in developing code? (and, applicable language if unique >>> to *a* language or class of languages) >> >> What do you mean be "non-traditional"? > > I suspect we'd all agree that the ability to support "procedures" > is highly valuable (imagine writing a complex piece of code *without* > being able to invoke one). And, that adding support for functions > enhances this capability (though functions without procedures makes > little sense) >
What about functional programming languages? They don't have procedures in the same sense as in a procedural programming language like C. You do have functions, but they are rather different from C functions. Or BASIC? I believe some people make embedded software written in BASIC without procedures as such. I believe I understand roughly what you mean, but I think it would take quite an effort to give a decent rigorous definition. And the way you pose the question implies that people regularly use programming languages that are have "non-traditional" features. Does that mean you think some features of C are non-traditional (since the majority of embedded programmers use C), or that some people use C in a non-traditional manner, or that you are interested in people who use languages other than C? Perhaps a clearer question would be, "if you use a language other than C for your embedded programming, what language do you use and what feature(s) are particularly useful?".
> Call these (and similar) "traditional" features: "Givens". > >> The two languages I find most useful in developing embedded code are >> English and C, followed by Norwegian, C++ and assembly. >> >> If these count as "traditional", then maybe it would be Python - that's >> the language I use most for scripts, auxiliary programs, test programs, >> etc. >> >
On 3/6/2017 11:33 AM, George Neuner wrote:
> On Sun, 5 Mar 2017 16:03:25 -0700, Don Y <blockedofcourse@foo.invalid> > wrote: > >> A quick/informal/UNSCIENTIFIC poll: >> >> What *single* (non-traditional) language feature do you find most >> valuable in developing code? (and, applicable language if unique >> to *a* language or class of languages) > > Closures. Far more useful than (OO) objects.
But doesn't this complicate the run-time (e.g., drag in GC)? Or, can all of this (subsetted) be handled at compile time?
On 3/6/2017 2:11 AM, Dimiter_Popoff wrote:
> On 06.3.2017 &#1075;. 01:03, Don Y wrote: >> A quick/informal/UNSCIENTIFIC poll: >> >> What *single* (non-traditional) language feature do you find most >> valuable in developing code? (and, applicable language if unique >> to *a* language or class of languages) > > Flexibility/expandability. In vpa if I miss something for a while > I can simply implement it rather than work around it every time.
Are you thinking of superficial/syntactic differences (e.g., things that could be addressed with a macro preprocessor)? Or, genuine semantic differences (e.g., adding interprocess communication operators to a language that doesn't currently support it)?
> Flexibility also means that being the lowest sensible level it > allows me to go to higher levels of abstraction without changing > language (with high level languages you can do that too on the > way up, not so on the way down hence the tons of workarounds/ > manufacturer libraries/templates etc. "unchangeable" thing > which dominate nowadays). > > IOW the most useful part of using vpa is the one which makes its > use like using an alphabet as opposed to using a phrase book (the > case with higher level languages).
On 3/6/2017 1:33 PM, David Brown wrote:
> On 06/03/17 16:47, Don Y wrote: >> On 3/6/2017 12:40 AM, David Brown wrote: >>> On 06/03/17 00:03, Don Y wrote: >>>> A quick/informal/UNSCIENTIFIC poll: >>>> >>>> What *single* (non-traditional) language feature do you find most >>>> valuable in developing code? (and, applicable language if unique >>>> to *a* language or class of languages) >>> >>> What do you mean be "non-traditional"? >> >> I suspect we'd all agree that the ability to support "procedures" >> is highly valuable (imagine writing a complex piece of code *without* >> being able to invoke one). And, that adding support for functions >> enhances this capability (though functions without procedures makes >> little sense) >> > > What about functional programming languages? They don't have procedures in the > same sense as in a procedural programming language like C. You do have > functions, but they are rather different from C functions. > > Or BASIC? I believe some people make embedded software written in BASIC > without procedures as such. > > I believe I understand roughly what you mean, but I think it would take quite > an effort to give a decent rigorous definition. And the way you pose the > question implies that people regularly use programming languages that are have > "non-traditional" features. Does that mean you think some features of C are > non-traditional (since the majority of embedded programmers use C), or that > some people use C in a non-traditional manner, or that you are interested in > people who use languages other than C? > > Perhaps a clearer question would be, "if you use a language other than C for > your embedded programming, what language do you use and what feature(s) are > particularly useful?".
There's no need to bind the discussion to C -- or any other language. I suspect most folks (i.e., damn near everyone) has used more than one language in their career. And, formed preferences for particular languages largely based on what the language allowed them to *do* -- and, at some fuzzy point in time, they thought to themselves: "<previous_language> wouldn't let me *do* things like this!" Limbo won't let me use pointers. I consider that a *huge* handicap as my coding style relies heavily on them in ways that feel "clumsy" to approximate using the mechanisms that Limbo supports in their stead. OTOH, I can type "a few characters" and communicate with another process (even on a remote node) without all the cruft of having to open a connection to that process (as well as figuring out *where* it resides).
On 6.3.17 09:40, David Brown wrote:
> On 06/03/17 00:03, Don Y wrote: >> A quick/informal/UNSCIENTIFIC poll: >> >> What *single* (non-traditional) language feature do you find most >> valuable in developing code? (and, applicable language if unique >> to *a* language or class of languages) > > What do you mean be "non-traditional"? > > The two languages I find most useful in developing embedded code are > English and C, followed by Norwegian, C++ and assembly. > > If these count as "traditional", then maybe it would be Python - that's > the language I use most for scripts, auxiliary programs, test programs, > etc. >
Which Norwegian: Bokmal or Nynorsk? For non-traditional languages, how about APL - cryptic, for sure? -- -TV
On Mon, 6 Mar 2017 13:36:49 -0700, Don Y <blockedofcourse@foo.invalid>
wrote:

>On 3/6/2017 11:33 AM, George Neuner wrote: >> On Sun, 5 Mar 2017 16:03:25 -0700, Don Y <blockedofcourse@foo.invalid> >> wrote: >> >>> A quick/informal/UNSCIENTIFIC poll: >>> >>> What *single* (non-traditional) language feature do you find most >>> valuable in developing code? (and, applicable language if unique >>> to *a* language or class of languages) >> >> Closures. Far more useful than (OO) objects. > >But doesn't this complicate the run-time (e.g., drag in GC)? >Or, can all of this (subsetted) be handled at compile time?
Not necessarily. Closures don't require GC at all unless they can persist beyond their definition scope. Think about nested functions as in Pascal, but augmented with private persistent variables (trying to avoid the word "static" to prevent unwanted associations with C). This form of closure is stack-strict and does not require any heap allocation[1]. Such closures are confined to the scope in which they are defined, so a little thought (vs C) has to be given to program structure. But many programmers successfully used Pascal and modular descendants of it ... it isn't *that* hard. <grin> Nested functions do require a little bit of runtime bookkeeping. A "display" (static scope array) is generally more performant than scope links in call frames. The size of the display for the program/module is fixed at compile time, and because it is accessed frequently (at every function call/return), it tends to cache quite well. If you are providing GC anyway, then IMO there is no reason not to provide 1st class closures as they are just a small object containing a pointer to the code and a pointer to a separate heap allocation for the persistant variables[2]. Closure objects can be handled like any other data. If you want GC to clean up unneeded code as well, that gets a little more interesting. You need to know the size of the code block to deallocate it, and it needs a global "name" (like any other data) so that closures can reference it. When there are no more closure objects referencing the block, it can be deallocated. [Obviously, there is a race condition: what if GC runs before any closures referencing the code block are created? Best way to handle that is deliberate unloading of the containing module. Alternatively you could use (compiler directed) reference counting and define a special count value to indicate the block should be retained despite currently having no references.] George [1] persistant variables can be heap allocated rather than stack allocated to reduce/control stack size. In either case the persistant variables would be defined as a structure (de)allocated by the *surrounding* scope rather than by the closure function itself. [2] if there are no shared persistant variables, then a closure object can contain them directly rather than having a pointer to a separate allocation. This saves an indirection at runtime, but at the expense of more complexity in the compiler (non-uniform handling of shared vs non-shared variables).
On Mon, 06 Mar 2017 22:15:38 -0500, George Neuner
<gneuner2@comcast.net> wrote:


>Nested functions do require a little bit of runtime bookkeeping. A >"display" (static scope array) is generally more performant than scope >links in call frames. The size of the display for the program/module >is fixed at compile time, and because it is accessed frequently (at >every function call/return), it tends to cache quite well.
Forgot to mention: you can lambda-lift and remove the need for any kind of scope links iff the program is a single module. But lambda-lifting doesn't work across modules. George