HN user

PySlice

37 karma
Posts0
Comments41
View on HN
No posts found.

However it's going to take some time to learn all the gotchas in string functions... Failing to zero-terminate strings (strncpy), potential buffer overflows (many), global internal buffer and overwriting an argument (strtok), etc etc etc etc

I think your comment is spot-on. A good Perl programmer can do wonders, but if you add just one average programmer to the team (without a very extensive training), he can write stupid things faster than the good programmer could fix, LOL. Then the codebase would be a mess, with things that kinda work but are conceptually wrong or weird for those who really know the language.

And the good programmer could do anything in a less eccentric language anyway, so...

I guess they just ran out of names, after deprecating java.util.Date (remember that there's also java.sql.Date).

If programmers of functional languages were better at naming things, it would be easy. Let's rename g to callTwice and h to aFunction:

  function callTwice(aFunction) {

    return function(y) {
      return aFunction(aFunction(y));
    };

  }

  function square(x) { return x*x; }

  var squareTwice = callTwice(square);

  81 === squareTwice(3);

What one can learn from Perl:

When programming in a language you hate, don't take naming arguments for granted. It could be worse: you could be programming in Perl, where all arguments come in a flattened array.

I don't think that is a misconception.

Perl is the language with the highest occurrence of "subtle" and "ambiguous" in its documentation and tutorials that I have ever seen. Humans may be subtle and ambiguous, but programming languages should be clear and precise.

The standard music notation and the criticism this new notation receives here look to me as if we were stuck for centuries with only one programming language, C++, and nobody could change it.

Sure, it has been working fine for many years, and a die-hard fan of C++ would come up with many criticisms of anything new: No pointers? It's for beginners only. Garbage collection? I can see the programmers that created it are not very proficient. Etc. etc. etc.

And you know what? There are really great programming languages that do many things differently and also work very well, or even better than C++. They are not perfect, but the traditional way of doing things (C++ or the standard music notation) was not perfect either to begin with.

So, I hope people experiment more and more with new notations, and maybe they will improve the standard notation or even replace it someday.

Explicit vs. Clever 13 years ago

After your excelent suggestions for names (makeMapper and makeGetter, they make everything easier, thank you), I'll try answering this, with a F#-like syntax using redundant parentheses around arguments to make them more explicit to those who don't know F#

Let's suppose map is defined as:

> let map (aList) (aFunction) = ...something here...

(this is according to https://github.com/raganwald/allong.es/blob/master/README.md which seems to have the parameters reversed when compared to F#'s Seq.map, Lis.map, etc.)

And let's suppose applyLast is defined as:

> let applyLast (aFunction) (anArgument) = (fun (x) -> aFunction (x) (anArgument))

So makeMapper is:

> let makeMapper = applyLast (map)

Read the above as: makeMapper is a function just like applyLast, but the first argument (to applyLast) is already provided, being "map". The functionality of applyFirst is implicit when the remanining parameters are missing, so we only need applyLast.

So makeMapper is called as

> let mapperWithAGetter = makeMapper (aGetter)

This completes the call to applyLast, so now we have a (fun (x) -> map (x) (aGetter))

Now we only need to bind x. The result is called like this

> mapperWithAGetter (aList)

IMO, all of this could've been written as:

> let makeMapper (aGetter) = fun (aList) -> map (aList) (aGetter)

Or:

> let makeMapper (aGetter) (aList) = map (aList) (aGetter)

Read both as: makeMapper takes aGetter and returns a function which takes aList

Notice that everything would be much easiear if map took aFunction as its first parameter:

> let map (aFunction) (aList) = ...

> let makeMapper = map // duh

Remember that partial application is implicit!

It would also be easier if applyLast had better syntax, using _ for the missing parameter (the first), as in this Scala-like snippet:

> def makeMapper(aGetter: Any => Any): List[Any] => List[Any] = { _.map(aGetter) }

(I guess Haskell has some nice syntax for this too, but I don't think F# has anything like this)

All of this was not easy to get right, I hope I didn't make any mistake regarding the position and number of parameters.

Explicit vs. Clever 13 years ago

Your example is great, but it would be even more convincing if it used list comprehension syntax such as

totals = [order.total for order in orders]

(like some other poster in this thread did)

Then you don't even need to know what "map" means, you only need to know "for" (well, maybe you would need an insight that "order" is defined after its use, but I digress)

Explicit vs. Clever 13 years ago

Can I upvote you twice?

More than once I have found about a new technique in language A and thought: "Wow, this is clever". Then sometime later I learnt language B where that technique is not only common place, but has some nice syntax sugar and is used throughout the whole standard library. And that makes a huge difference in the perceived cleverness of the code.

I went in the other direction and it was enlightening too. I learned how useful hash tables can be, and that a word count algorithm need not be a complicated assignment full of segmentation faults. :-)

I also learned how data structure libraries can be separated from user code (when learning C in class we usually created ad-hoc data structures heavily coupled with the calling code).

That logic is just a starting point (just to avoid the "I don't need it, why can't you be just like me?"), not the whole thing.

Then you have to take into account a few other criteria, such as [1] internal coherence in the language, [2] difficulty in implementation (and explaining to others) [3] what your target audience is, and what they want, [4] what competitors are doing.

I think full operator overloading would hurt [2], but special-casing Bignums would not hurt [1], [2] at all (as I said, JSP EL already have +,-,*,/, etc. , String already have +, +=).

[3] This is what this thread is all about, no need to repeat :-D

And [4]... Well in this case Java is really playing catch up.

I remember some years ago when I was glad Java 5 had got some really practical new features. I didn't program in Java back then, but I wanted the language to evolve (maybe I was going to need it in the future).

Now I do program in Java 5/6 and it would be really sad if the language was still stuck in the 1.4 days.

> Thus, getters and setters should not be encouraged.

Damn, so why are they encouraged in Java? 11 out of 10 frameworks insist that you write getters/setters so properties can be accessed from outside.

Java designers need to get more practical. If getters/setters are unavoidable, I'd better have them without so much boilerplate in my code.

No need to go the C# way. Just enough to avoid repeating the name and type 3+ times each would be great.

Me too. However, I don't think Java needs much to become an appealing language (for language-geeks).

It's already going to get lambdas. Add some shortcuts for getters and setters (Lombok-style, maybe) and collections literals, then you get surprisingly close to Groovy (and JPA @Entity classes will become 1/6 of their sizes). And just like Strings have special + and +=, Bignums could have some compiler help (as they already do in JSP EL).

It will still be behind C#, but not by much. At that point I could agree that Java and C# have different philosophies and Java will never get true operator overloading, but it doesn't matter much if the most important use cases are covered.

Yeah, I guess it sucks if you work with Bignums. I would be happy if BigInteger and BigDecimal were promoted String-level language support: still implemented as classes, but with compiler support. They could add indexing [] for collections, but I can live with .get() and .put().

Some people seem to think that if they don't use, then it doesn't matter. In many business applications, you don't even need floating point (you just transfer data to the database and back), anyway.

Are floats and doubles "little features"?

In computer graphics, you need lots of floating point calculations. Are ints and longs "little features"?

In embedded software, you usually don't want to use resizable strings (C doesn't even have this feature built-in), because reallocations are expensive or unavailable. Are resizable strings (or containers) "little features"?

Different programs have different needs. If you haven't stumbled upon a good use case, doesn't mean that it's useless.

To me, checked exceptions seem to be a second return value: you need to catch it or declare that you are going to pass it to the caller. In this sense, it is enforced by the compiler even more rigidly than the return values themselves. They can be useful.

OTOH, sometimes we need a "panic"(¹) function, and a main loop that catches everything and either communicates the error to the user, or restarts the whole thing. That's why unchecked exceptions can be useful too, especially since they makes it harder to ignore errors - who has the patience required to check every return value of printf in C?

(¹) No, I've never programmed in Go.

I wonder what those dogmatic programmers do when they are confronted with a problem in the real world where they need to find a balance between "encapsulation" and "single responsibility".

I guess their brains simply deadlock.