HNHacker News
TopNewBestAskShowJobs

jestar_jokin

305 karma · joined February 8, 2010

submissionscomments
jestar_jokin··on Blue. No, Yellow
Ah, you're referring to the halting problem? You're right, you can't know every possible value. The article I linked actually mentions how Idris approaches the problem:

    The word "total" invokes the totality checker[0] which will report an error if the function doesn't cover all possible cases or cannot be (automatically) proven to not enter an infinite loop.
So, it sounds like if you can't provably account for all possible inputs, the compiler will recognise this and throw an error. How? Magic! (And a solver, feeding your type constraints into the totality checker, I guess...)

(Also, bear in mind languages like Haskell use "lazy" or "non-strict" evaluation by default, where values aren't evaluated until they're actually needed; kiiiinda like Streams?)

I'm certainly not an expert on Idris, but I imagine dependent typing provides two benefits:

1) The type signature (which is separate from the implementation; kind of like an Interface in Java) can enforce constraints on your implementation. So, if you define a function with type sig of "Int a => Int b => (a + b)", your implementation must ensure that the returned value is equal to the sum of the two inputs.

2) You can look purely at the type signature to understand what a function is doing. Looking at that type signature above, I can see I want to use that function for addition, not multiplication.

Anyway, I'm absolutely not doing justice to these ideas (mostly because I'm not well acquainted with the languages). If you're curious at all, I would highly recommend taking a course on functional programming as a minimum; once I realised that names are meaningless in code, you start seeing everything as reducible to very similar type signatures, which makes you yearn for a language that lets you write your boilerplate once, in a polymorphic way (beyond generics).

[0] https://en.wikipedia.org/wiki/Termination_analysis

jestar_jokin··on Blue. No, Yellow
Not as such; functional languages use "pattern matching", so you are forced to match each possible outcome. This way, it explicitly brings the issue of nulls out into the open; if you have a Maybe it might be null, if you have a String, or Number, or anything else, it is never null!

This means the language allows you to define areas of your program that are null-safe, and areas where nulls are expected.

Compare to languages where you must remember to check null on every use of a null variable. I guarantee I can pick any Java codebase and find a method where arguments to that method, or a class's properties, are not checked for null on every use. How do I know that the use is safe? Usually by coding conventions; maybe immutable instances represented by values set only in a constructor, although what's to stop null being passed in?

jestar_jokin··on Blue. No, Yellow
Well, I don't know Idris in detail, so you're better off reading the wiki page I linked to, but I will try to explain further.

Idris allows you define types whose definition depends on a value - these are called "dependent types". This allows you to define a type such as "a pair of integers, where the second integer is greater than the first".

So, in your example, you could define an immutable String type that stores its length as a fixed value. Then, you define a function that accepts a String of length "len", and a Num (or Integer) with a value that must be less than "len". The type signature might look something like this (if I understand the syntax correctly):

    ngram : String len val => Num (a <= len) => Vect Num String
jestar_jokin··on Blue. No, Yellow
Regarding nulls, have a look at how Haskell deals with nulls. The basic idea is that any nullable value gets wrapped in a "Maybe", and you use pattern matching to handle the case of missing/empty values. This is much more explicit than null values in Java, where any object could be null at any time, and actually leads to cleaner code (i.e. to avoid lots of "Maybe" boilerplate, you can match for "Nothing" and return a default value as soon as possible to first matching "Nothing").

Regarding illegal arguments, have a look at something like Idris, which has a type system with "dependent types". The Wikipedia page has an example[0]; types can have values, so you can express a "pairAdd" function that accepts two vectors, each vector requiring the same length.

I guess "types" and "compile-time checks" are sometimes used interchangeably. I absolutely think tools (such as compilers) should be leveraged to provide as much assistance as possible; whether that comes in the form of types, or some other mechanism that resembles types.

[0] https://en.wikipedia.org/wiki/Idris_(programming_language)#D...

jestar_jokin··on Reason: A new interface to OCaml
A similar language might be Haxe, which can target C++, Java, C#, PHP, JavaScript, Python, Lua, and Neko languages, and make use of the tooling/build chain for those languages.

So you can abstract the syntax from the runtime, but the semantics are often different per target - e.g. accessing the filesystem in Node.js will be different to C++, due to the non-blocking I/O mechanism.

As an aside, the Haxe compiler is written in OCaml. I think there'd be a delicious juxtaposition if it was re-written in Reason. Writing Reason to generate OCaml to create Haxe to generate Java to generate bytecode...

jestar_jokin··on Am I really a developer or just a good Googler?
I do it for attribution, partly out of respect to the original authors, and partly to help resolve any licensing issues that may arrive - e.g. "This code was taken from a site with no clear license on its use, so we may need to replace it at some point."
jestar_jokin··on Show HN: Larder, bookmarking for developers
This looks like a great idea! I've been using Pocket for storing dev stuff with the intention of organising it, but never get around to reading anything. Hopefully having folders will help.

Really, as long as I can quickly assign or create a category at the time I saved the bookmark, I'll be happy.

jestar_jokin··on Hello Lua
Some targets will have different behaviours regarding null[1], mostly for static language targets; e.g. basic types that are represented by primitives cannot be null when targeting C#, Java, Flash, or C++. Dynamic language targets don't have this issue. (Can be avoided by wrapping your values in Null<T>).

Overflow is normally not handled consistently[2]; it's left up to the target platform to define the overflow behaviour. E.g, JS only has one numeric type (a 64-bit floating point), and can't represent integers over 52-bits. Can be avoided by using Int32 and Int64 classes, but this reduces the code interop if you want to export a library (consumers would need to make use of the Haxe representation of a 64-bit integer).

Arrays aren't fixed sized; if you want this, you need to use Vectors[3], which aren't interface-compatible with Arrays, so you can't use them as a drop-in replacement. (Compare this to Java's Collections API.)

File system access isn't available on every platform, e.g. JS, Flash. If you target Node.js you can use the file system, you just can't use the normal file API, so you need to write stuff specific to each target.

Dates are, as always, a pain to deal with. Timezones aren't supported by the Date class[4]. DateTools.makeUtc() is not available on some platforms[5].

The built-in database API is only accessible on C++, Neko (Haxe-specific bytecode/runtime), and PHP[6]. AND it only seems to support MySQL. This has stymied my ideas about a cross-language multi-DB ORM.

Basically, you have to intimately know the gotchas of every language you target, and if you already know them you may as well write in that language.

Having said all that, Haxe seems to be greatly improving these abstractions with every release; I think given enough time, it will become an amazing tool. I'm starting to use it in place of Python as my "go to" language. For most purposes you can just use a single target; Neko works well for most functionality, but you can always target C++ for "true" cross-platform compatibility and performance, and JS for the browser.

[1] http://haxe.org/manual/types-nullability.html

[2] http://haxe.org/manual/types-overflow.html

[3] http://api.haxe.org/haxe/ds/Vector.html

[4] http://api.haxe.org/Date.html

[5] http://api.haxe.org/DateTools.html

[6] http://api.haxe.org/sys/db/Mysql.html

jestar_jokin··on Hello Lua
cURL was created by Daniel Stenberg, Haxe was created by Nicolas Cannasse. (EDIT: beaten)

My favourite Haxe feature is compile-time macros. This leads to massive meta-programming and language extension capabilities. My least favourite aspect is that it does not strictly unify or abstract every target language & runtime, so you end up writing in that language's semantics but using Haxe as syntax sugar. (Good for C++, less useful for other targets.)

jestar_jokin··on Xamarin Open-Sourced
Seriously, RoboVM could have been huge. An ingenious way to introduce app development to your existing hordes of Java devs. Great tech, killed because of business decisions...
jestar_jokin··on Sample workflow for LP digitization
Yes, there are. Any sound card that supports XLR connector mics will probably support phantom power and have a built-in mic amp, a vinyl pre-amp is not much different. I use an E-MU 1212m with a microdock, making it equivalent to a 1616m, which offers a "Turntable Input (w/ground lug and hardware RIAA preamp)".

http://www.creative.com/emu/products/product.aspx?pid=19007

jestar_jokin··on Freedom and security issues on x86 platforms
Java has precedent for running on low-performing devices; see J2ME[0], which ran on a whole bunch of old mobile phones, and Java Card[1], which ran on smart cards.

https://en.wikipedia.org/wiki/Java_Platform,_Micro_Edition

https://en.wikipedia.org/wiki/Java_Card

jestar_jokin··on Google Nik collection now available for free
Any idea if this could work with GIMP using something like the "GIMP PSPI plugin"?
jestar_jokin··on NPM and Left-Pad: Have We Forgotten How to Program?
"Addressed" doesn't mean "solved!" ;)

Yes, you're right, making use of dynamic behaviour will break DCE.

jestar_jokin··on An administrator accidentally deleted the production database
Earlier in my career, I worked in prod support for an insurance web application. It had a DB containing reference data. This reference data was maintained in an Excel spreadsheet; a macro would then spit out CSV files, which would be used by command line scripts to populate databases in different environments (test, staging, pre-production). The DB data was totally replaced each time. Pre-production data would be copied into production, every night or so.

One time, I ran the staging and pre-production scripts at the same time. This had the unusual effect of producing an empty CSV file for pre-production.

When I got in the next day, I discovered all of the production data had been wiped out overnight...

Thankfully, it was all reference data, so it was just a matter of re-running the export macros, and pleading with a DBA to run the data import job during business hours.

I ended up writing a replacement using generated SQL, so we could apply incremental updates (and integrate better with a custom ticketing system).

jestar_jokin··on NPM and Left-Pad: Have We Forgotten How to Program?
Joining an array of strings is sometimes better than concatenating a string in place, yes.

Consider the following:

  1: var str = 'foo';
  2: str += 'bar';
  3: str += 'baz';
At program load, you have three string constants, 'foo', 'bar', and 'baz'. At 1, 'str' becomes a pointer to the string constant 'foo'. At 2, 'str' becomes a pointer to a string 'foobar'. Memory is allocated to store this string. At 3, 'str' becomes a pointer to a stinrg 'foobarbaz'. Memory is allocated to store this string.

Now consider the following:

  1: var str = ['foo', 'bar', 'baz'].join('');
At program load, you have three string constants, 'foo', 'bar', and 'baz'. At 1, 'str' becomes a pointer to the string constant 'foobarbaz'. In the array concatenation, the JS interpreter can create a single string buffer large enough to contain the contents of each array element and the separator string * N - 1 (where N is the number of elements), and return a pointer.

Once you have a large number of elements, or are joining large strings, the performance difference (especially regarding garbage collection) could matter.

jestar_jokin··on NPM and Left-Pad: Have We Forgotten How to Program?
Point 1 was addressed years ago by Google Closure Compiler, which used "dead code elimination".

Also, the Haxe language, which compiles to JS, has DCE.

Micro-modules is certainly a solution if you don't want to use pre-processing or compilers. So is copy/pasting, or manually writing your own util libs, which seems safer than relying on third parties to provide one-liners for you.

jestar_jokin··on NPM and Left-Pad: Have We Forgotten How to Program?
So, in the context of this discussion... you should make use of micro-modules to reduce code duplication, avoid defects, etc. However, don't expect those micro-modules to be maintained or available in the future; so you need to set up your own package cache to be maintained in perpetuity.

Or, you can implement the functionality yourself (or copy/paste if the license allows) and avoid the hassle.

jestar_jokin··on Faking Co-Routines, or Why Callback Hell Is Over (2014)
Unfortunately, Node.js decided that every callback should accept an error as the first argument to every callback. If you're chaining a bunch of callbacks, it's tedious and error-prone to add boilerplate to check for an error and handle it consistently in every callback, and violating the DRY principle. It's not easy to simply propagate the error to a higher-level handler.
jestar_jokin··on Faking Co-Routines, or Why Callback Hell Is Over (2014)
I believe async/await uses promises behind the scenes. It just means invoking code looks nicer, i.e writing "var res1 = await prom1(a); await prom2(a, res1)" is marginally cleaner than "return prom1(a).then((res1) => prom2(a, res1));", in the sense that you're just writing statements rather than chaining method invocations.
jestar_jokin··on Simple coroutines for games in C++
I recommend having a look at the source code for ScummVM. The original SCUMM engine, first used in Maniac Mansion, implemented its own VM with cooperative multithreading, way back on the C64.

Basically, the game ran "scripts" (containing custom bytecode), each given its own "slot" with space for locals. Each script is run in turn, and each script must voluntarily relinquish control when appropriate.

Of course, this is a bit more advanced than simple coroutines. If you're going to the effort of creating your own embedded scripting language, you may as well an existing language like Lua.

Example code: https://github.com/scummvm/scummvm/blob/master/engines/scumm...

jestar_jokin··on Brendan Eich: WebAssembly is a game-changer
Eclipse (Che) is already coming to the browser!

https://eclipse.org/che/

jestar_jokin··on Data Structures in JavaScript
Maybe implementing a virtual machine would be more suitable? You can practice a lot of the same essentials.

- Memory management can be simulated by have a fixed length array, representing your total RAM, and somehow marking index ranges as "reserved". - You can simulate some hardware devices by exposing browser capabilities. Each, you could print a character, by writing to a virtual port or register (actually implemented as an array), then later in your VM update loop, reading the values in the array, interpreting the instructions, and updating the DOM as approprite.

And all from the comfort of your browser!

You could check out some emulators that have been ported to JavaScript; these are simulating hardware like the NES, and have the capability to run operating systems.

jestar_jokin··on Python 3 Is Winning Library Developer Support
I've found, building Python binaries for Windows, the interpreter and standard library takes up a negligible amount of space (a few MB). Most of the space was taken up by dependencies anyway, e.g. wxPython something like 15 MB! (I think I got it down to 7 MB using UPX to compress the DLLs.)
jestar_jokin··on Lamdu – towards a new programming experience
Isn't this the "sunk cost fallacy"? i.e. we've spent X effort-years creating text-based tools, might as well keep going with them, even if there's a potentially better way of programming?

Imagine semantic version control that can parse your AST and tell you which methods, expression, classes, functions etc were modified, instead of just syntax changes like "this line of text is different because you added a semicolon."

I'd love to see more semantic-focused tools, eventually leading to generic solutions that work across any AST. Polyglot IDEs like IntelliJ IDEA can come close, but only because they implement their own parsers, to derive an... AST!

jestar_jokin··on Palette Gear: Hands-On Control of Your Favourite Software
With a bit of work, you can get similar functionality using off-the-shelf MIDI controllers and AutoHotKey. Here's my efforts:

- Map sliders and buttons on a Novation Nocturn to media keys (volume, play, stop, mute etc). - Map a foot pedal (Behringer FCB1010) to a virtual joystick, for use in Euro Truck Simulator 2.

AHK is super powerful for Windows automation, so I'm sure you create more sophisticated mappings that tweak the "Saturation" value when a certain window or dialog is open.

I think given the range of MIDI controllers available, this would give you more options for physical inputs. Can you imagine using a "Yamaha WX5 MIDI Wind Controller" to control Photoshop?

jestar_jokin··on Imba: A new programming language for web apps
- Don't worry, there's only a few different paradigms in use by the different libraries and frameworks out there. Just look at the examples and see which one piques your interest.

- Do some analysis to break down your problem into manageable steps, until you reach steps small enough to action. For example, a task tracking board might have the following components: columns (representing "status"), drag and drop (which changes the position of some DOM elements, plus updates the task status), and a form (to capture the task status). So, look for ways to solve each of those problems. e.g. column might be made easier using a grid layout system, such as provided by Bootstrap. Drag and drop can be handled using HTML5 features. And form handling can be made easier (or fancier) using any number of libraries out there.

I wouldn't jump on a brand new language for the purpose of solving a problem, if you don't have a clear idea of the solution you would like to implement. Writing code is a means to an end, not a goal itself. It'd be easier to write a solution using methods you're familiar with, then rewriting it using different technologies.

jestar_jokin··on Heroku is no longer the hobbyist's friend
Note that, for some reason, they limit regions that can use their paid tiers. So, you can't use them if you're in third world countries like Australia or New Zealand.
jestar_jokin··on Anorexia May Be Habit, Not Willpower, Study Finds
From a rationalist perspective, relying on "willpower" is the same as just saying "I should really do that" without action to follow. To make changes in your behaviour, you should rely on forming habits, and you should make it as easy as possible to fall into those habits. This is how "fake it until you make it" works.

(Obviously, things get tricky if you have a mental illness.)

jestar_jokin··on Open source projects for modern COBOL development
BigDecimal doesn't count? (I guess because it's "Big" rather than efficient.)
← PreviousPage 3 of 6Next →