April 26, 2018
On 4/26/2018 3:29 PM, Nick Sabalausky (Abscissa) wrote:
> The theory goes:
> 
> A. "less syntax => easier to read".
> B. "There's no technical need to require it, and everything that can be removed should be removed, thus it should be removed".
> 
> Personally, I find the lack of parens gives my brain's visual parser insufficient visual cues to work with, so I always find it harder to read. And regarding "B", I just don't believe in "less is more" - at least not as an immutable, universal truth anyway. Sometimes it's true, sometimes it's not.

Haskell seems to take the "minimal syntax" as far as possible (well, not as far as APL which has a reputation for being write only). Personally, I find it makes Haskell much harder to read than necessary.

Having redundancy in the syntax makes for better, more accurate error diagnostics. In the worst case, for a language with zero redundancy, every sequence of characters is a valid program. Hence, no errors can be diagnosed!

Besides, redundancy can make a program easier to read (English has a lot of it, and is hence easy to read). And I don't know about others, but I read code an awful lot more than I write it.

I posit that redundancy is something programmers learn to appreciate as they gain experience, and that eliminating redundancy is something new programmers think is a new idea :-)

P.S. Yes, excessive redundancy and verbosity can be bad. See COBOL.
April 26, 2018
On Thu, Apr 26, 2018 at 07:14:17PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
> On 04/26/2018 06:47 PM, H. S. Teoh wrote:
> > 
> > If "less is more" were universally true, we'd be programming in BF instead of D.  :-O  (Since, after all, it's Turing-complete, which is all anybody really needs. :-P)
> > 
> 
> Yea. Speaking of which, I wish more CS students were taught the the inherent limitations of "Turing-complete" vs (for example) "Big-O". There's faaaar too many people being taught "Turing-complete means it can do anything" which, of course, is complete and total bunk in more (important) ways than one.

Actually, Turing-complete *does* mean it can do anything... well, anything that can be done by a machine, that is.  There are inherently unsolvable problems that no amount of Turing-completeness will help you with.

The problem, however, lies in how *practical* a particular form of Turing-completeness is.  You wouldn't want to write a GUI app with lambda calculus, for example, even though in theory you *could*. (It would probably take several lifetimes and an eternity of therapy afterwards, but hey, we're talking theory here. :-P)  Just like you *could* write basically anything in machine language, but it's simply not practical in this day and age.


And actually, speaking of Big-O, one thing that bugs me all the time is that the constant factor in front of the Big-O term is rarely considered.  When it comes to performance, the constant factor *does* matter.  You can have O(log n) for your algorithm, but if the constant in front is 1e+12, then my O(n^2) algorithm with a small constant in front will still beat yours by a mile for small to medium sized use cases.  The O(log n) won't mean squat unless the size of the problem you're solving is commensurate with the constant factor in the front. You can sort 5 integers with an on-disk B-tree and rest assured that you have a "superior" algorithm, but my in-memory bubble sort will still beat yours any day.  The size of the problem matters.

Not to mention, constant-time setup costs that's even more frequently
disregarded when it comes to algorithm analysis.  You may have a
O(n^1.9) algorithm that's supposedly superior to my O(n^2) algorithm,
but if it takes 2 days to set up the data structures required to run
your O(n^1.9) algorithm, then my O(n^2) algorithm is still superior
(until the problem size becomes large enough it will take more than 2
days to compute).  And if your O(n^1.9) algorithm has a setup time of 10
years, then it might as well be O(2^n) for all I care, it's pretty much
useless in practice, theoretical superiority be damned.

And that's not even beginning to consider practical factors like the hardware you're running on, and why the theoretically-superior O(1) hash is in practice inferior to supposedly inferior algorithms that nevertheless run faster because they are cache-coherent, whereas hashing essentially throws caching out the window.  Thankfully, recently there's been a slew of papers on cache-aware and cache-oblivious algorithms that are reflect reality closer than ivory-tower Big-O analyses that disregard reality.


> I see the same thing in other areas of CS, too, like parser theory. The formal CS material makes it sound as if LR parsing is more or less every bit as powerful as LL (and they often straight-up say so in no uncertain terms), but then they all gloss over the fact that: That's ONLY true for "detecting whether an input does or doesn't match the grammar", which is probably the single most UNIMPORTANT characteristic to consider when ACTUALLY PARSING.  Outside of the worthless "does X input satisfy Y grammar: yes or no" bubble, LL-family is vastly more powerful than LR-family, but you'd never know it going by CS texts (and certainly not from those legendary-yet-overrated Dragon texts).

Well, LR parsing is useful for writing compilers that tell you "congratulations, you have successfully written a program without syntax errors!".  What's that?  Where's the executable?  Sorry, I don't know what that word means.  And what?  Which line did the syntax error occur in?  Who knows!  That's your problem, my job is just to approve or reject the program in its entirety! :-P

(And don't get me started on computability theory courses where the sole purpose is to explore the structure of the hierarchy of unsolvable problems.  I mean, OK, it's kinda useful to know when something is unsolvable (i.e., when not to waste your time trying to do something that's impossible), but seriously, what is even the point of the tons of research that has gone into discerning entire *hierarchies* of unsolvability?!  I recall taking a course where the entire term consisted of proving things about the length of proofs. No, we weren't actually *writing* proofs. We were proving things *about* proofs, and I might add, the majority of the "proofs" we worked with were of infinite length.  I'm sure that it will prove (ha!) to be extremely important in the next iPhone release, which will also cure world hunger and solve world peace, but I'm a bit fuzzy on the details, so don't quote me on that.  :-P)


T

-- 
Your inconsistency is the only consistent thing about you! -- KD
April 26, 2018
On Thu, Apr 26, 2018 at 04:26:30PM -0700, Walter Bright via Digitalmars-d wrote: [...]
> Having redundancy in the syntax makes for better, more accurate error diagnostics. In the worst case, for a language with zero redundancy, every sequence of characters is a valid program. Hence, no errors can be diagnosed!
> 
> Besides, redundancy can make a program easier to read (English has a lot of it, and is hence easy to read).

People often complain about how redundant natural languages are... not realizing that it actually provides, in addition to being easier to read, some degree of built-in error-correction and resilience in a lossy medium.  Think of reading a text that has occasional typos or omitted words.  Most of the time, you can still figure out what it's saying in spite of the "syntax errors".  Or talking over the phone with lots of static noise.  You can still make out what the other person is saying, even if some words are garbled.  Computer languages aren't quite at that level of self-correctiveness and resilience yet, but I'd like to think we're on the way there.

Redundancy is not always a bad thing.


> And I don't know about others, but I read code an awful lot more than I write it.

Yes, something language designers often fail to account for.

Well, many programmers also tend to write without the awareness that 5 months later, someone (i.e., themselves :-D) will be staring at that same piece of code and going "what the heck was the author thinking when he wrote this trash?!".


> I posit that redundancy is something programmers learn to appreciate as they gain experience, and that eliminating redundancy is something new programmers think is a new idea :-)
> 
> P.S. Yes, excessive redundancy and verbosity can be bad. See COBOL.

And Java. ;-)


T

-- 
INTEL = Only half of "intelligence".
April 27, 2018
On Thursday, 26 April 2018 at 22:29:46 UTC, Nick Sabalausky (Abscissa) wrote:
> On 04/26/2018 01:13 PM, arturg wrote:
>> 
>> why do people use this syntax?
>> 
>> if val == someVal
>> 
>> or
>> 
>> while val != someVal
>> 
>> it makes editing the code harder then if you use if(val == someVal).
>
> The theory goes:
>
> A. "less syntax => easier to read".
> B. "There's no technical need to require it, and everything that can be removed should be removed, thus it should be removed".
>
> Personally, I find the lack of parens gives my brain's visual parser insufficient visual cues to work with, so I always find it harder to read. And regarding "B", I just don't believe in "less is more" - at least not as an immutable, universal truth anyway. Sometimes it's true, sometimes it's not.

yeah same here,
and if people find delimiters anoying, editors with syntax highlighting can help with that by making them less visible so the important content sticks out more.

But not having some delimiter removes the ability to edit the text by using for exemple vims text object commands (vi(, yi[, and so on).
In this regard, ddoc's syntax is anoying because the identifier is inside the parens:
$(somemacro, content)
it would have been better if it was:
$somemacro(content).
Which can make html more editable then ddoc :/ as vim recognises tags as text objects.
April 27, 2018
On Friday, 27 April 2018 at 00:03:34 UTC, H. S. Teoh wrote:
> Actually, Turing-complete *does* mean it can do anything... well, anything that can be done by a machine, that is.

No, it means there's some *abstract mapping* between what a thing can do and what any Turing machine can do.  That sounds pedantic, but it makes a difference.

For example, early C++ template metaprogamming was Turing complete, but it couldn't do much of the code generation that's possible nowadays.  Sure, there's a theoretical abstract function that maps the problem you're really trying to solve to a complex C++ type, and then template metaprogramming could convert that to a "solution" type that has a theoretical mapping to the solution you want, but there weren't any concrete implementations of these abstract functions you needed to get the actual code generation you wanted.

Inputs and outputs are usually the killer of "but it's Turing complete" systems.
April 27, 2018
On 04/26/2018 08:03 PM, H. S. Teoh wrote:
> On Thu, Apr 26, 2018 at 07:14:17PM -0400, Nick Sabalausky (Abscissa) via Digitalmars-d wrote:
>> On 04/26/2018 06:47 PM, H. S. Teoh wrote:
>>>
>>> If "less is more" were universally true, we'd be programming in BF
>>> instead of D.  :-O  (Since, after all, it's Turing-complete, which
>>> is all anybody really needs. :-P)
>>>
>>
>> Yea. Speaking of which, I wish more CS students were taught the the
>> inherent limitations of "Turing-complete" vs (for example) "Big-O".
>> There's faaaar too many people being taught "Turing-complete means it
>> can do anything" which, of course, is complete and total bunk in more
>> (important) ways than one.
> 
> Actually, Turing-complete *does* mean it can do anything... well,
> anything that can be done by a machine, that is.  There are inherently
> unsolvable problems that no amount of Turing-completeness will help you
> with.
> 

It's directly analogous to the LR vs LL matter, and LR's "Well, I can tell you this input does/doesn't satisfy the grammar, but I can't help ya with much more than that":

Turning-completeness only tells you whether a given Turing-complete system (ie, "language", machine, etc) *can* compute XYZ if given infinite time and memory resources. That's it, that's all it says. (Granted, that *is* still a useful thing to know...)

However, Turing-completeness says nothing about whether the given language can accomplish said task *in the same time complexity* as another Turing-complete language. Or any other resource complexity, for that matter.

And Turing-completeness also says nothing about what inputs/outputs a language/system has access to.

Ex: VBScript is Turing-complete, but it can't do direct memory access, period, or invoke hardware interrupts (at least not without interop to another language, at which point it's not really VBScript doing the direct memory access, etc). This means there are things that simply cannot be done in VBScript.

Another example:

Alan's Turing machine (as well as the BF language) is incapable of O(1) random-access. Accessing an arbitrary memory cell is an O(n) operation, where n is the difference between the target address and the current address. But many other languages/machines, like D, ARE capable of O(1) random-access. Therefore, any algorithm which relies on O(1) random-access (of which there are many) CANNOT be implemented with the same algorithmic complexity in BF and it could be in D. And yet, both BF and D are Turing-complete.

Therefore, we have Turing-complete languages (BF, VBScript) which are INCAPABLE of doing something another Turing-complete language (D) can do. Thus, Turing-completeness does not imply a language/machine "can do anything" another language/machine can do.

And then, of course, *in addition* to all that, there's the separate matter you brought up of how convenient or masochistic it is to do ABC in language XYZ. ;)


> And actually, speaking of Big-O, one thing that bugs me all the time is
> that the constant factor in front of the Big-O term is rarely
> considered.
> [...]
> And that's not even beginning to consider practical factors like the
> hardware you're running on, and why the theoretically-superior O(1) hash
> is in practice inferior to supposedly inferior algorithms that
> nevertheless run faster because they are cache-coherent, whereas hashing
> essentially throws caching out the window.  Thankfully, recently there's
> been a slew of papers on cache-aware and cache-oblivious algorithms that
> are reflect reality closer than ivory-tower Big-O analyses that
> disregard reality.
> 

Certainly good points.

> Well, LR parsing is useful for writing compilers that tell you
> "congratulations, you have successfully written a program without syntax
> errors!".  What's that?  Where's the executable?  Sorry, I don't know
> what that word means.  And what?  Which line did the syntax error occur
> in?  Who knows!  That's your problem, my job is just to approve or
> reject the program in its entirety! :-P

Exactly! :)

(Ugh, I would've saved myself sooooo much bother if ANY of that had been even remotely clear from any of the parsing books I had read. But nope! One of the items on my bucket list is to write a "CS Theory for Programmers" book that actually fills in all this stuff, along with going easy on the math-theory syntax that you can't realistically expect programmers to be fluent in. The average CS book is the equivalent of marketing a "How to speak German book" in the US...but writing it in French. Sure, *some* Americans will be able to read it, but...)

> (And don't get me started on computability theory courses where the sole
> purpose is to explore the structure of the hierarchy of unsolvable
> problems.  I mean, OK, it's kinda useful to know when something is
> unsolvable (i.e., when not to waste your time trying to do something
> that's impossible), but seriously, what is even the point of the tons of
> research that has gone into discerning entire *hierarchies* of
> unsolvability?!  I recall taking a course where the entire term
> consisted of proving things about the length of proofs. No, we weren't
> actually *writing* proofs. We were proving things *about* proofs, and I
> might add, the majority of the "proofs" we worked with were of infinite
> length.  I'm sure that it will prove (ha!) to be extremely important in
> the next iPhone release, which will also cure world hunger and solve
> world peace, but I'm a bit fuzzy on the details, so don't quote me on
> that.  :-P)

Well, I think a big part of it is the general acceptance that we can never really be certain what knowledge will/won't be useful. So science is all about learning whatever we can about reality on the presumption that the pursuit of scientific knowledge is a virtue in and of itself. Maybe it's all the Star Trek I've watched, but I can get onboard with that[1].

The part where things really start to bug me, though, is when the scientific knowledge *does* cross outside the realm of pure science, but in the process gets misrepresented as implying something it really doesn't imply, or critically important details get ignored or under-emphasised[2].

[1] Although I would certainly prefer to see preferential focus placed on scientific inquiries that ARE already known to have practical, real-world impact (like: "Can this LR parser (which we can theoretically create to validate the same grammar as some LL parser) be constructed to emit the same parse-tree as the LL parser? (Hint: Probably not) If so, what costs are involved?")

[2] It also bugs me how they say "abstract" when they don't actually mean "abstract" at all, but really mean "summary" or "overview", but...well...that's considerably less important ;)
April 27, 2018
On Friday, 27 April 2018 at 04:06:52 UTC, Nick Sabalausky (Abscissa) wrote:
> One of the items on my bucket list is to write a "CS Theory for Programmers" book that actually fills in all this stuff, along with going easy on the math-theory syntax that you can't realistically expect programmers to be fluent in. The average CS book is the equivalent of marketing a "How to speak German book" in the US...but writing it in French. Sure, *some* Americans will be able to read it, but...)

The first Haskell tutorial I read was written by someone who thought it would be cute to do mathsy typesetting of all the syntax.  E.g., -> became some right arrow symbol, meaning that nothing the book taught could be put into an actual Haskell compiler and executed.  The book never explained the real syntax.

Thankfully there are more useful tutorials out there (like this one: http://learnyouahaskell.com/).
April 27, 2018
On Fri, Apr 27, 2018 at 06:22:55AM +0000, sarn via Digitalmars-d wrote: [...]
> The first Haskell tutorial I read was written by someone who thought it would be cute to do mathsy typesetting of all the syntax.  E.g., -> became some right arrow symbol, meaning that nothing the book taught could be put into an actual Haskell compiler and executed.  The book never explained the real syntax.

Ouch.

That's cruel!


T

-- 
Never wrestle a pig. You both get covered in mud, and the pig likes it.
April 27, 2018
On Friday, 27 April 2018 at 00:18:05 UTC, H. S. Teoh wrote:
> On Thu, Apr 26, 2018 at 04:26:30PM -0700, Walter Bright via Digitalmars-d wrote: [...]
>> [...]
>
> People often complain about how redundant natural languages are... not realizing that it actually provides, in addition to being easier to read, some degree of built-in error-correction and resilience in a lossy medium.  Think of reading a text that has occasional typos or omitted words.  Most of the time, you can still figure out what it's saying in spite of the "syntax errors".  Or talking over the phone with lots of static noise.  You can still make out what the other person is saying, even if some words are garbled.  Computer languages aren't quite at that level of self-correctiveness and resilience yet, but I'd like to think we're on the way there.
>
> Redundancy is not always a bad thing.
>
>
>> [...]
>
> Yes, something language designers often fail to account for.
>
> Well, many programmers also tend to write without the awareness that 5 months later, someone (i.e., themselves :-D) will be staring at that same piece of code and going "what the heck was the author thinking when he wrote this trash?!".
>
>
>> [...]
>
> And Java. ;-)
>
>
> T

Yep. Good point. German is more redundant than English (case endings) and it's easier to re-construct garbled text. But natural languages tend to remove redundancy (e.g. case endings when the relation is clear) - up to a certain point! But redundancy is needed and good. Maybe natural languages show us how far you can go before you get in trouble.
April 28, 2018
On Thursday, 26 April 2018 at 23:26:30 UTC, Walter Bright wrote:
> Besides, redundancy can make a program easier to read (English has a lot of it, and is hence easy to read).

I completely agree. I always make an effort to make my sentences as redundant as possible such that they can be easily read and understood by anyone:

Buffalo buffalo buffalo buffalo buffalo buffalo buffalo buffalo.

Unfortunately, I think the Chinese have us beat; they can construct redundant sentences far beyond anything we could ever imagine, and thus I predict that within 50 years Chinese will be the new international language of science, commerce, and politics:

Shíshì shīshì Shī Shì, shì shī, shì shí shí shī. Shì shíshí shì shì shì shī. Shí shí, shì
shí shī shì shì. Shì shí, shì Shī Shì shì shì. Shì shì shì shí shī, shì shǐ shì, shǐ shì shí shī shìshì. Shì shí shì shí shī shī, shì shíshì. Shíshì shī, Shì shǐ shì shì shíshì. Shíshì shì, Shì shǐ shì shí shì shí shī. Shí shí, shǐ shí shì shí shī shī, shí shí shí shī shī. Shì shì shì shì.

石室诗士施氏,嗜狮,誓食十狮。氏时时适市视狮。十时,适十狮适市。 是时,适施氏适市。氏视是十狮,恃矢势,使是十狮逝世。氏拾是十狮尸,适石室。石室湿,氏使侍拭石室。石室拭,氏始试食是十狮尸。食时,始识是十狮,实十石狮尸。试释是事。