Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 1:49 pm

tufty,
Keeping things exact until it's absolutely necessary to approximate them is good practice if you care about the correctness of your result.
Sounds like a good plan.

Seems to me it's ultimately a losing proposition whatever you do. Any real world calculation will involve messy things like PI, root 2, e, and the like. Never mind simple messy things like 1/3. Once you get into that your calculations are by definition not "exact". So the question is how hard do you want to, or need to, work to get workably close to the right results. It's then a trade off between accuracy vs computational work (speed) and memory usage.
I'd put it as close to exactly one third of the way from zero to one as I could.
Exactly. Which involves a division one way or another to get the single thing you need rather than the two numbers you are given.

Thanks for the scheme collatz. Now we can have a good giggle at how unreadable and slow scheme is :)

More seriously I think scheme is a wonderful thing. At least conceptually.

Story goes that when Brendan Eich was hired by Netscape to make a scripting language for the browser he wanted to make something inspired by Self. Which is in turn inspired by Self. The management said no way, make something that looks like a normal language (C, Java, Pascal...) that people can understand.

So we got JS. Looks a bit like Java but with some of the sophisticated features of Self/Lisp.
Last edited by Heater on Fri Dec 16, 2016 6:08 pm, edited 1 time in total.

jahboater
Posts: 2858
Joined: Wed Feb 04, 2015 6:38 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 2:16 pm

Heater wrote:However, it's very annoying that so much of that is "implementation dependent". That means you can never be sure your program works on all compilers and architectures. WTF?
Well, you can if you study the language standards documents carefully, and abide by secure coding standards such as CERT https://www.securecoding.cert.org and MISRA https://www.misra.org.uk/Publications/t ... fault.aspx.
My point is that few programmers do.
Heater wrote:I also find it insane that C will happily overflow an integer or whatever, produce an undefined result and then happily continue producing garbage.
Signed integer overflow cannot happen in a correct C program!

Most programmers want a loop such as "for( int i = 0; i < 100; ++i )" to increment with a single add or inc insn as we all know it cannot overflow. To have it check for overflow 100 times (e.g. with -ftrapv) is a no-no. Better for the programmer to explicitly check a-priori for the odd case where overflow is possible. But that check must not itself cause an overflow.
Last edited by jahboater on Fri Dec 16, 2016 2:29 pm, edited 2 times in total.

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 2:25 pm

Heater wrote:Seems to me it's ultimately a losing proposition whatever you do. Any real world calculation will involve messy things like PI, root 2, e, and the like. Never mind simple messy things like 1/3. Once you get into that your calculations are by definition not "exact".
That's really not even close to being true.

Floating point is great, for what it's good at. What it's good at is giving a rough approximation of the correct result, as fast as possible. That's fine - as you say, it comes down to a tradeoff - but I contend that for computing that deals with the real world, which includes stuff like engineering, spaceflight, airworthiness, and calculating the repayments on your mortgage, you can't live with the unpredictable error factors involved in floating point. Just the trivial fact that, as far as floating point is concerned, 20 * 1/10 ≆2 makes it unacceptable for the latter. Remember, tenths don't represent exactly in floating point, and money is nothing if not full of tenths. That said, floating point works fine for engineering. As long as you're dealing with imperial :P

Sure, for chucking stuff about in a 3d game world, it's fine and dandy, especially given GPU acceleration for floating point (but even then, there are wrinkles, floating point error has an uncanny ability to make itself visible where you least want it), but if you're dealing with millions of financial transactions, combined error can make the difference between making a profit and making the headlines. Of if you're aiming a spaceship over millions of kilometers it's the difference between making an orbit or making a crater.
Heater wrote:
I'd put it as close to exactly one third of the way from zero to one as I could.
Exactly. Which involves a division one way or another to get the single thing you need rather than the two numbers you are given.
But you've already done that division. I'm just doing it later, to get a more exact result. If it turns out the number scale is a multiple of 3, I'm quids in.
Heater wrote:Now we can have a good giggle at how unreadable and slow scheme is :)
Oh, for sure. I'll make the harness clearer; I slapped it together in a fit of "make it work". It *is* slow, though. That's the price you pay for mathematical completeness with no number-theoretical edge cases. There's ways to make it use machine-defined integer types, but it's ugly, nonportable, full of edge cases, and pretty much guaranteed to fail at some point. Unsurprisingly, it's much like C, in that respect :)

Still, at least it's not BASIC, eh?

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 2:48 pm

Here you go. A bit cleaner.

Code: Select all

;;; Basic Collatz for a number
(define (collatz x)
  (let loop ((x x) (count 0))
    (cond
     ((= 1 x)   count)
     ((even? x) (loop (/ x 2) (+ count 1)))
     ((odd? x)  (loop (+ (* x 3) 1) (+ count 1))))))

;;; Collatz for a number, explicitly fixnum
(define (collatz-fx x)
  (let loop ((x x) (count 0))
    (cond
     ((fx=? 1 x)   count)
     ((fxeven? x) (loop (fxdiv x 2) (fx+ count 1)))
     ((fxodd? x)  (loop (fx+ (fx* x 3) 1) (fx+ count 1))))))

;;; Collatz for a number, explicitly fixnum using arithmetic shift for divide
(define (collatz-fxshift x)
  (let loop ((x x) (count 0))
    (cond
     ((fx=? 1 x)   count)
     ((fxeven? x) (loop (fxarithmetic-shift-right x 1) (fx+ count 1)))
     ((fxodd? x)  (loop (fx+ (fx* x 3) 1) (fx+ count 1))))))

;;; Quick macro to wrap some code in a timer
(define-syntax timed
  (syntax-rules ()
    [(_ x)
     (let ((start-time (current-time)))
       x
       (let ((d (time-difference (current-time) start-time)))
         (display (format " elapsed time : ~a.~a seconds\n"  (time-second d) (time-nanosecond d)))))]))

;;; Function carrying out a Collatz function over values 1 ... n, timed
(define (collatz-test n fn)
  (timed
   (let loop ((x 1) (max-x 0) (max-count 0))
     (if (> x n)
         (display (format "max ~a, count ~a," max-x max-count))
         (let ((count (fn x)))
           (if (> count max-count)
               (loop (+ x 1) x count)
               (loop (+ x 1) max-x max-count)))))))

;;; Do the test
(let ((n 10000000))
  (display "Plain Collatz ")
  (collatz-test n collatz)
  (display "Explicitly fixnum ")
  (collatz-test n collatz-fx)
  (display "Explicitly fixnum with shifts for divide ") 
  (collatz-test n collatz-fxshift))

User avatar
[email protected]
Posts: 1979
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: Making readable modifyable code.

Fri Dec 16, 2016 3:20 pm

tufty wrote: Still, at least it's not BASIC, eh?
Give someone a vaguely useful tool and they'll abuse it... Think of all those financial spreadsheets that feel foul of the Pentium divide bug - so Excel (LO/OO) uses hardware floating point? (I don't use it enough to know how to switch it into fixed point mode - assuming it has such facility)

As for BASIC - well it gets abused in many ways - I wonder if Bill Gates saw a future version of his BASIC wrapped as a "spreadsheet macro"... Or a virus transport mechanism... I've seen stuff done by people in RTB I shouldn't be surprised about, but I am... One enterprising person has written a large financial analysis program in it... another has written an I2C stack in it (using floating point numbers as integers - what was I thinking when I gave them bit-operations!) Controlling model railways is just the tip of the iceberg...

Most basics I know of just use the native underlying hardware - whatever the native (or convenient) integer size is and native floating point - RTB is no exception there - everything is a C double... Anything more clever is left as an exercise for the user ;-)

-Gordon
--
Gordons projects: https://projects.drogon.net/

timrowledge
Posts: 1136
Joined: Mon Oct 29, 2012 8:12 pm
Location: Vancouver Island
Contact: Website

Re: Making readable modifyable code.

Fri Dec 16, 2016 5:48 pm

Smalltalk provides Fraction as a class within its numeric hierarchy, so ⅓ is a perfectly acceptable number. Clearly doing maths with fractions will be slower since you get to operate on both numerator and denominator and then for added fun you need to do the whole least common divisor dance - but it works, and keeps precision.

So far as I recall (from knowing the folk that did it) Self is actually derived from Smalltalk, not Lisp.
Making Smalltalk on ARM since 1986; making your Scratch better since 2012

Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 6:11 pm

timrowledge,

Ah yes, Self not Lisp. Thanks for the correction.

I corrected my post. The gist is the same though. The Netscape management wanted something normal people can deal with.

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 6:23 pm

Brendan Eich gave a very interview, which covers the development of Javascript, https://devchat.tv/js-jabber/124-jsj-th ... endan-eich
I started looking at languages like Logo and Smalltalk and Self and HyperTalk which was Bill Atkinson’s language for HyperCard … people say JavaScript is powered by Self. There was very little Self in fact, because I had so little time.

Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Fri Dec 16, 2016 10:35 pm

Wow, tufty, thanks for the link to that interview. It's great to hear the story from original sources.

The whole JS story is pretty amazing. Starting with the 10 days to build a prototype. It took me a couple of months or more to build a very simple compiler for a very simple Pascal like language. Even when spoon fed all the details of how to do it!

Interesting that Brendan says BASIC was not an inspiration. However he was obviously driven by some of the same ideas that made the original Dartmouth BASIC. That is, to be easily accessible to beginners.

User avatar
scruss
Posts: 1776
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: Making readable modifiable code.

Fri Dec 16, 2016 10:44 pm

tufty wrote:Still, at least it's not BASIC, eh?
Do I get to make the indignant cry of “Not all BASICs!” here?

Some BASICs have the option of using decimal arithmetic. Back in the day, even Microsoft shipped two versions of BASIC for Macintosh, one decimal, one binary:
Decimal_vs_Binary_BASIC.png
Decimal vs Binary arithmetic in MS Basic for Macintosh
Decimal_vs_Binary_BASIC.png (5.85 KiB) Viewed 4966 times
They even had slightly different icons: the decimal interpreter had a $ where the binary one had π. You don't have to go back in time to find a decimal BASIC, either: the ANSI Full BASIC standard has it. Admittedly there are few implementations, but if you can get the Lazarus Pascal IDE 1.6 running on your Raspberry Pi (too much work for me this aft, but I did get it to build on x86_64) you can build Decimal BASIC.

As for the 2901 bit slice ALUs, I got them in A-1 Electronics in Toronto. They have some might weird things, like ancient ASCII LED segment displays and thousands of GI speech chips. If anyone wants to play with a 2901, I have several spare.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Sat Dec 17, 2016 12:15 am

tufty,

That's really not even close to being true. ...

Of course it is true.

You cannot have "exactness" when dealing with irrational numbers, or transcendentals. That would require an infinite amount of memory, even if you had the infinite amount of time to calculate what they were "exactly".

Even if you are talking about simple rational numbers, 1/3, 5/9, etc, I can still invent a rational that has so many digits in it's dividend and denominator that your machine cannot handle it exactly.

So, you have to draw the line somewhere.

When it comes to engineering, spaceflight, airworthiness the precision we have, be it fixed point or floating point, has proved to be good enough. It's amazing how we landed man on the moon with so few bits of precision!
Remember, tenths don't represent exactly in floating point, and money is nothing if not full of tenths.
True. When I said "real world" I did not mean the artificial world of money, book keepers and accountants. Those guys will run around for days until they track down a 1 cent error in the books. Then charge their client a thousand dollars for doing so.

They turn a rounding error into a major loss!
Still, at least it's not BASIC, eh?
Thank God for small mercies!

ejolson
Posts: 1843
Joined: Tue Mar 18, 2014 11:47 am

Re: Making readable modifiable code.

Sat Dec 17, 2016 12:21 am

scruss wrote:Back in the day, even Microsoft shipped two versions of BASIC for Macintosh, one decimal, one binary:
Do you know how many decimal digits of precision Microsoft decimal BASIC had? Was it possible to specify the precision? I wonder how many emulators running old versions of Microsoft BASIC are being used to accurately calculate those national-debt-sized numbers and how much the legacy-support contract costs.

User avatar
scruss
Posts: 1776
Joined: Sat Jun 09, 2012 12:25 pm
Location: Toronto, ON
Contact: Website

Re: Making readable modifyable code.

Sat Dec 17, 2016 3:00 am

It looks like MS BASIC has about 15-18 digits of decimal precision. No-one would seriously still use this, though, as Visual BASIC supports Decimal types.
‘Remember the Golden Rule of Selling: “Do not resort to violence.”’ — McGlashan.

User avatar
DougieLawson
Posts: 33636
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Making readable modifyable code.

Sat Dec 17, 2016 8:37 am

My brother got a bucket load of grief from an Amstrad customer (he was their telephone helpdesk wonk at the time) because "This beep beeep beeping Amstrad can't get it's maths right". He had a proper struggle explaining the joys of floating point base 10 versus floating point base 2 and the decimal anomalies that injects.
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

jahboater
Posts: 2858
Joined: Wed Feb 04, 2015 6:38 pm

Re: Making readable modifyable code.

Sat Dec 17, 2016 9:16 am

Heater wrote: You cannot have "exactness" when dealing with irrational numbers, or transcendentals. That would require an infinite amount of memory, even if you had the infinite amount of time to calculate what they were "exactly".

Even if you are talking about simple rational numbers, 1/3, 5/9, etc, I can still invent a rational that has so many digits in it's dividend and denominator that your machine cannot handle it exactly.
The point is, with IEEE 754, you do know when the result is not exact (when the result is not the same as the infinite precision result).

1.0/3.0 or sqrt(2.0) will raise the inexact exception (or set the sticky flag - visible in C as fetestexcept(FE_INEXACT)). 2.0/4.0 or sqrt(4.0) will not. The hardware gets it right.

Then you deal with it, increase the precision, keep it as a fraction or whatever. The important thing is that you know.

The software doesn't always get it right cbrt(27) will incorrectly raise inexact as will "sqrt(2) * 0.0" etc but that's another matter.

By default the exceptions are masked so the sticky flag is normally used.

ejolson
Posts: 1843
Joined: Tue Mar 18, 2014 11:47 am

Re: Making readable modifyable code.

Sun Dec 25, 2016 6:21 am

DavidS wrote:I know that I posted a similar topic the other day, though it dissapeared never to be heard from again, so I am posting this similar, though slightly different topic.
I just wanted to wish the person who started this thread and his family every possible blessing this Christmas. Hoping you are back in the new year. All the best.

Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Sun Dec 25, 2016 5:26 pm

Yes, all the best for DavidS. And Merry Christmas to all.

callahanp
Posts: 9
Joined: Wed Apr 13, 2016 2:49 pm
Location: Framingham, Ma, USA
Contact: Facebook Google+ Skype

Re: Making readable modifyable code.

Sun Jan 07, 2018 8:36 pm

I've seen lots of advice over the last 50 years on how to write readable code. Most of it focused on what I think of as "typography" and "layout". Another good bit of it focused on how to name variables in either the problem domain or the domain of programming constructs in one language or another. Most of it focuses on writing as if all that needs to be understood about a section of code is "what it does". Never mind why, or how it fits into the larger picture.

Perhaps the most important thing that makes code readable is the readers ability to read and understand what's going on.

Can we learn to be better writers of code by learning to read better?

What skills are involved in reading and understanding code?

Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Mon Jan 08, 2018 12:05 am

Wow, this is a good old thread.

I have come to the conclusion that it's impossible.

So many times in my career I have found myself thrown into a project with a huge code base. Often written in a language I have never used before. That's problem number 1.

I have no idea what this code does or why it does it, unless I start to understand the thousands of pages of requirements document or otherwise find out what it should do. That is problem number 2.

Then, the code structure and it's details may well be written in a way that does not map directly to that requirement. For performance reasons perhaps. Problem number 3.

It has happened that I get to work with a code base where even the comments in the code are written in a human language I do not speak. Not difficult as I only speak one. Problem number 4.

I could go on.

Let's take a simple example. If you have done some maths in school you might know what a Fourier Transform is. In school we see it as a calculus thing with integrals and such. There is a simple way to do that on a computer using discrete signal samples and summation.

But that is not how the Fast Fourier Transform algorithm works. It looks totally different. If you don't understand the maths behind it there is no way in hell you are going to understand what the code does or how it does it.

Then there is the question of who is the target audience. Like writing anything. Filling your code up with trivial comments will annoy your peers working on the thing. Better not have any comments mostly. They soon fall out of phase with changes in the code, then they just add confusion.

jahboater
Posts: 2858
Joined: Wed Feb 04, 2015 6:38 pm

Re: Making readable modifyable code.

Mon Jan 08, 2018 8:49 am

The attributes of a good program might be:-

1) simple
2) readable
3) robust
4) correct
5) portable
6) general
7) standards conforming

Readability is just one of many important things to aim for.

Heater
Posts: 9726
Joined: Tue Jul 17, 2012 3:02 pm

Re: Making readable modifyable code.

Mon Jan 08, 2018 2:34 pm

jahboater,

Sounds like worthy aims.

1) correct/robust

I don't know if your list was in any particular order but I'm going to put "correct" first. After all, most of all, we want the thing to work. I'm going to combine it with "robust" for the same reason.

Unfortunately, in general, correctness is impossible to prove. Robustness even more so. See every security advisory ever.

2) portable

This is a high priority because:

a) In my experience getting code to run on different OS, processor architectures, word size machines, etc often shows up bugs in the original code. It also encourages separation of low level interfacing concerns from application concerns. Such modularity helps with correctness.

It sure helps "robustness", when a platform disappears you can still run the thing else where.

3) standards conforming

Clearly important. Having well defined and predictable compilers, libraries, protocols etc enables portability and contributes to correctness/robustness.

4) simple

Yes because I need to understand my own code after not looking at it for a year or whatever!

However, nothing non-trivial is ever simple. Especially when optimizations have had to be employed.

5) readable

Yes. But by whom? Clearly I need sufficient hints in my code to remind myself of how and why it works, for myself a year later as I said. On a collaborative project team members need "notes" to each other but perhaps not on the level of detail that an outsider would need to get into the thing quickly.

6) general

Hmmm....I put this last. This can be a negative, an "anti-pattern".

First order of the day is to get a solution to a problem working. Trying to make it general will add code you don't need. Waste time trying to as you try to think of the general use cases and handle them. Introduce bugs. The "generality" certainly won't get tested much as you only have one problem scenario at the time.

Making things general is hard. Designing a clean, simple, general API is hard. Better to leave that until you come to another problem that requires a similar solution, then you can pull out and clean up common code.

jahboater
Posts: 2858
Joined: Wed Feb 04, 2015 6:38 pm

Re: Making readable modifyable code.

Mon Jan 08, 2018 3:09 pm

Heater,

Yes, the list was (roughly) ordered.

Of course correctness is the prime goal. But I placed simplicity first because simple code is much more likely to be correct, and importantly is likely to remain correct over time.

Robust code that is resilient to random future changes and environmental changes is also more likely to remain correct over time.

The same is true for readability, code that is hard to read, is hard to maintain, leading to bugs in the future.

Simple, clean, general, code is extremely difficult to write and only the best engineers can produce it.
Obviously (as you say) that is relative, in that a complex project has, inevitably, to be complex, but poor engineers will make it more complex than it needs to be.

I regard the original engineers who designed UNIX (and C, and the C library with its ecosystem) as truly great, they produced simple, general, designs that have stood the test of time. Compare the elegance of UNIX with the old mainframe OS's of the day, on one side and things like MSDOS on the other.
I'm going to put "correct" first. After all, most of all, we want the thing to work.

Unfortunately, in general, correctness is impossible to prove.
Yes indeed. But what is correctness?
Conformance to requirements? successful testing?
In C and probably most other fast, well standardized, languages, we have "undefined behavior", "unspecified behavior", and "implementation defined behavior".
Code exhibiting these may:- work correctly, may crash, may produce incorrect results, maybe anything. But importantly it may work and pass all the tests. Until something changes, or the customer does something unexpected.
So I rate standards conformance highly.

I forgot to add "maturity". Not something you can engineer of course, but (as you said) porting a program to many platforms, real usage in the field, and so on, helps make a solid program.

ejolson
Posts: 1843
Joined: Tue Mar 18, 2014 11:47 am

Re: Making readable modifyable code.

Tue Jan 09, 2018 6:40 am

jahboater wrote:
Mon Jan 08, 2018 8:49 am
The attributes of a good program might be:-

1) simple
2) readable
3) robust
4) correct
5) portable
6) general
7) standards conforming

Readability is just one of many important things to aim for.
This is similar to the "Worse-is-Better" model of software design which prioritizes as

1. Simplicity
2. Correctness
3. Consistency
4. Completness

See for example

https://en.wikipedia.org/wiki/Worse_is_better
https://www.jwz.org/doc/worse-is-better.html
http://minnie.tuhs.org/pipermail/tuhs/2 ... 09935.html

The argument that simplicity takes priority over correctness is interesting.

jahboater
Posts: 2858
Joined: Wed Feb 04, 2015 6:38 pm

Re: Making readable modifyable code.

Tue Jan 09, 2018 8:26 am

Thats very interesting especially this link
https://www.jwz.org/doc/worse-is-better.html
Both lists of attributes put simplicity first.

I was talking about simplifying code to meet a given fixed set of requirements.
They are talking about trimming the entire design down which is a different thing.
For example UNIX was simpler and had less functionality than say OS360 or Multics at the time, but it had far far less bugs (and was therefore more correct) and was ultimately more successful.
The argument that simplicity takes priority over correctness is interesting.
Sounds wrong doesn't it - since correctness is an absolute.
But simplicity engenders correctness, both now and in the future.

ejolson
Posts: 1843
Joined: Tue Mar 18, 2014 11:47 am

Re: Making readable modifyable code.

Wed May 09, 2018 2:43 am

I thought I would update this thread with a link to a version of the collatz algorithm written in Scatch, which, by the way, also appears quite readable and modifiable to me.

Return to “General programming discussion”

Who is online

Users browsing this forum: No registered users and 2 guests