electric-segfault
electric-segfault
Seg.Fault();
58 posts
Welcome to my Programming Rant Blog!!
Don't wanna be here? Send us removal request.
electric-segfault · 7 years ago
Text
I Love Rust
By that I mean Rust the programming language, not Rust the videogame; sorry to anyone coming here thinking this post was about that.
I've been trying to learn Rust the past few months, and I think I'm finally getting a grasp of it---at least to some extent---and as of late, I feel like the language has started to click into place for me.
For those who don't know, I have a pretty diverse theoretical background in programming. In 2012 I learned C# at a "profession academy", in 2013 I learned Scala and Haskell out of my own curiosity, in 2014 I learned ANSI C (aka C89) as part of an imperative programming course at the university, and in 2017 I dabbled with some C++ as part of an embedded programming project.
In a sense, my interests have always been a mix of procedural and functional code (functional in the sense of FP, not in the sense that the code works). When I write C#, I go out of my way to make the code as functional as possible, relying heavily on delegates (C#'s closures) and Linq to bend the various collection types to my will. One could argue that this functional approach to C# comes as a result of my intense love for Scala, which marries FP with OOP in an interesting natural way.
In comes Rust. I would mostly describe the language as a weird merger between C++ and Scala, in fact, I'm surprised more people don't make the syntactic connection between the languages; take this example:
Scala
def safeDivide(a: Double, b: Double): Option[Double] = { return if(b != 0) Some(a / b) else None }
Rust
fn safe_divide(a: f64, b: f64) -> Option<f64> { if b != 0.0 { Some(a / b) } else { None } }
Apart from the different name for a 64-bit floating point number, and the explicit curly braces in if-statements, the languages are damn near identical in a lot of ways, even down to their use of Associated Types (called Abstract Types in Scala).
It is however important to note that Rust---unlike Scala---is not object oriented, even though it does use a few OOP ideas, the language itself is almost entirely procedural + functional, whereas Scala is object-oriented + functional.
Rust has no classes and no inheritance, but does instead have composition through traits, which are interface-like constructs with a few more built-in features. Traits let you extend existing types at will, and they even let you implement default behaviour similar to abstract classes.
The weird thing is that I feel at home in Rust---just like I do in Scala. Even though Rust is all about explicit programming, foregoing implicit conversions in favour of having the user type everything out, where Scala is quite literally the opposite, I still feel at home. It has that feeling of C's low-levelness which I actually really like. It also has all the cool constructs I love from Haskell. But unlike Haskell---as much as I love it---I feel like I actually get work done in it. It feels like a workhorse language, just like the C family of languages.
Just the other day I implemented a word generator for a constructed language I'm making, which was capable of taking in a sequence of rules, spitting out a string of letters, and I did it in like 56 lines of code. When that compiled, when it ran without a hitch, and worked exactly how I envisioned it I was completely blown away. I did that in less than 100 lines of code?! Doing something simiar in C# would require 4 times that; not because C# is a weak language by any means, but because of the sheer number of classes and files and ritualistic public static blah blah blah you need just to get any code running. Naturally, the current version of the code is a bit longer; somewhere around 74 lines of code, but that's due to the fact that I added a bit more functionality, including a few macros that make the writing of rule sequences incredibly painless and intuitive.
I think this code was when I realised Rust had clicked for me... At least a little bit. I still have troubles with it; some of the things about the language are a bit confusing to me still, but that's natural with any language, especially one with a learning curve as steep as Rust's---and steep it is.
Like C and C++, Rust does not have or use a runtime, and thus does not have a garbage collector. Sounds really annoying to work with, but actually not! For the most part, Rust's compiler does all the memory de-allocation for you before the code even runs! Following a set of very strict rules, Rust manages to know exactly when and where in a program memory needs to be de-allocated, so you don't have to do it yourself. This does of course mean you need to know exactly what you're doing, or Rust will tell you you're doing it wrong. "Fighting the borrow checker" is a common newbie issue in Rust, and for good reason, you basically have to throw every habit you have out the window, especially if you're coming from a language with a garbage collector.
That said, I still love it! My code might not be up to par with the best rustacians (the Rust-community word for a Rust-programmer), but it's slowly getting there.
If you're interested in the word generator I wrote, you can find it here: https://github.com/ElectricCoffee/word_generator
2 notes · View notes
electric-segfault · 7 years ago
Text
Why I Love Macros
Macros are one of those weird things that programmers sometimes hear about, but unless they're using a language that has them, they might think macros are weird, archaic, and/or useless. If their only prior exposure to macros have been through C/C++, I can kinda see where they're coming from.
Like most other features from Lisp, metaprogramming (aka macros) is slowly starting to creep into modern day programming languages. Scala has it, Clojure has it (being a Lisp dialect and all that), Haskell has it (through Template Haskell), JavaScript has it (through Sweet.js), and of course Rust has it.
Coming from a background of C/C++, macros are nothing but a simple text-replacement system, where the preprocessor runs through your code and replaces the text almost verbatim, a good example of a C macro that I've used a fair bit is this one:
#define foever for(;;)
so that I can write
forever { /* do repeat this forever */ }
All the macro really does, is have the preprocessor go in and replace every occurrence of the word forever, and replacing it with for(;;) (which is the same as while(true) for those uninitiated).
That's all great and all, but C/C++ macros are just text replacement macros, which means they don't have the power of "true" macros. If we take good ol' Lisp for example: since everything in Lisp is a list, that means the data within a macro definition is itself a list, which means we can do list manipulation on the program code itself! List concatenation, iteration, mapping, reducing, all that good stuff becomes possible when macros are data rather than simple preprocessor text!
Now, Lisp syntax is a bit too obtuse to give decent examples in without confusing people too much, so let's use Rust instead. Fair warning: I haven't used Rust enough to know if it has quite the same expressive power as Lisp macros, but it's certainly up there, judging by the lazy_static! macro.
A common example of Rust macros is the vec! macro, since it's very easy to implement and very easy to explain, so here we go.
The vec! macro is defined as follows:
macro_rules! vec { ($($x:expr),*) => ({ let mut vec = Vec::new(); $(vec.push($x);)* vec }) }
I'll explain what each line does in a moment, but let's first see it in action: if I write
let v = vec![1, 2, 3, 4];
the macro will actually expand that expression to this:
let v = { let mut vec = Vec::new(); vec.push(1); vec.push(2); vec.push(3); vec.push(4); vec };
That is to say, it creates a new scope, then an empty vector, pushes each value into it one by one, and then returns the vector out of the scope and into v.
Let's break down how this works then: on the first line we have macro_rules! vec {, which just means "define a new macro called vec".
Then we have the expression line that looks like this: ($($x:expr),* => ({, which just tells us that we have 0 or more metavariables called x that are separated by a comma. In this case x has to be an expression, which lets us write things like 2 + 3, 4, 2.pow(3) and so on.
On the next line let mut vec = Vec::new();, we define a new vector called vec, and then $(vec.push($x);)* just says "for every x, create a line vec.push($x);, where you replace $x with the corresponding expression.
Then lastly we have vec which simply tells us to return the vector out of the block.
It's super simple, and the syntax is actually a bit similar to regular expressions: * for "0 or more", and + for "1 or more". I believe Rust also has ? for "0 or 1".
So why is this useful? Because it lets you extend the syntax of the language to suit your needs! If you have any kind of long chain of something that you want to reduce down to just a few expressions, you can probably do it with a macro.
Rust's error handling syntax, the ? is just a macro behind the scenes, and it lets you write
let foo = f()?; let bar = g(foo)?; let baz = h(bar)?;
instead of
let foo = match f() { Ok(x) => x, Err(e) => return Err(e) }; let bar = match g(foo) { Ok(x) => x, Err(e) => return Err(e) }; let baz = match h(bar) { Ok(x) => x, Err(e) => return Err(e) };
The possibilities are virtually endless, and the joys are great! If your favourite language of choice has a macro system, I suggest giving it a go, because it's a great way of reducing otherwise painful boilerplate.
2 notes · View notes
electric-segfault · 8 years ago
Text
Why it’s a shame that XHTML died.
I've been doing a fair bit of web development over the years, and the more of it I do, the more I hate HTML. Why? Simple. It's fucking inconsistent.
HTML5 tags come in three flavours: <a></a>, <b/>, and <c>. The last one in particular is the one that makes me hate HTML5.
The thing about HTML5 is that it's never obvious when it's appropriate to use which tag. For example: <br> is correct, but <br/> is not, <img> is correct and <img/> is not. And the kicker: <script></script> is right, and <script/> is wrong.
Learning XML I was always taught that an opening tag needed a closing tag, and that an opening tag always without exception was followed by a closing tag, meaning that writing <foo> would always be wrong, and <foo></foo> would always be right, and that <foo/> was always just stand-in for a set of opening and closing tags.
So why is this a problem? Because it makes it impossible to write a HTML parser that knows how to deal with the tags properly; that is, unless you include special cases for all the tags that don't have closing tags... In XML/XHTML this isn't a problem at all because all the tags are completely uniform in their construction.
Example
Here's an example body of HTML code
<body> <h1>Hello, reader!</h1> <p>This is a simple example<br> of a broken up paragraph</p> <img src="my-image.png" alt="holiday photo"> <script src="my-script.js"></script> </body>
And now the same code in XHTML
<body> <h1>Hello, reader!</h1> <p>This is a simple example<br/> of a broken up paragraph</p> <img src="my-image.png" alt="holiday photo"/> <script src="my-script.js"/> </body>
Sure it all might just seem minor, after all the differences between the two examples aren't huge; but (to me) they're significant. All the tags are properly closed, it all looks neat and tidy, and look! The script line is actually shorter!
To me XHTML isn't more verbose, it's less confusing.
I mean sure, XHTML requires you to use this dreadful doctype and namespace:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml">
Which is much less nice than the simple <!DOCTYPE Html> found in HTML5. But I'd argue the payoff is worth it in the long run.
Or it would be if any modern frameworks and tools actually supported XHTML.
Oh how I wish XHTML would be resurrected...
24 notes · View notes
electric-segfault · 9 years ago
Text
On the subject of typing
I often hear the argument "Language X is/isn't a strongly typed language because Y". Often times this argument arises because the language is dynamically typed, and therefore it must not be static. Except that most dynamic languages today are strongly typed, even if it may not seem immediately obvious.
I often hear Python being cited as a weakly typed language because its function arguments don't require typing, or because you can assign a different type of value to the same variable name. One thing those people don't mention, is this:
>>> "hello" + 3 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Can't convert 'int' object to str implicitly
You actually need to manually convert the integer to a string before concatenating or else you'll get a type error. Weakly typed languages don't give you type errors.
Ruby does the exact same thing:
irb(main):001:0> "hello" + 3 TypeError: no implicit conversion of Fixnum into String from (irb):1:in `+' from (irb):1 from /usr/bin/irb:12:in `<main>'
And so does Common Lisp:
[1]> (+ "hello" 3) *** - +: "hello" is not a number
JavaScript by comparison just doesn't give a damn:
> "hello" + 3 'hello3'
One could argue that JS is strongly typed, it just has type coercion that converts things into the appropriate types before attempting to do an operation on them, which I guess is a fair point; after all the above example simply converts the number to a string before concatenating it with "hello". I mean both C# and Java do the same thing, they both implicitly call .toString() on an object if its string is needed, and nobody calls those languages "weakly typed".
What about PHP?
> "2" + 2; => 4
I don't know about you, but I don't think that's supposed to happen. And yet it does, because PHP isn't strongly typed. I have a feeling it's because everything in PHP is represented as a string internally to ease the burden of doing web-development. That also comes with the gotcha that any representation of a number, string or otherwise, is a legal number to do maths with.
That said, not just dynamically typed languages are weakly typed, a few static languages are too.
If you know C well enough, you'll soon realise that pretty much everything is a number internally, which can lead to some pretty freaky stuff if you do it with care.
Note the following example (C doesn't have an interactive mode like the others):
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char *str = "Hello, World!"; // set target string char *current = str; // set head of pointer to beginning while (*current != 0) { // while the string isn't 0 printf("%c\n", *current); // print the string pointer as a char current = current + 1; // add 1 to the string } return EXIT_SUCCESS; }
What's gong on here, is that I'm treating the string pointer current like an integer, adding 1 to it every time I've printed it. And since I know a string ends in a '\0' in C, '\0' having the ascii value 0, I can just check for it as such. And for those not familiar, C doesn't have strings, it instead uses char arrays and/or char pointers for that.
"But that's just pointer manipulation" I hear you cry. I know! That's my point, you can do this with structs and unions as well if you know your way around their internal memory representation. That's why I'd argue that C isn't strongly typed. C essentially allows you to add a struct to a string and get out the sum of their memory locations; and if you're going by the principle of least astonishment, then that's definitely not what you'd expect would happen.
In short:
Strong typing: Obeys type rules, types can't be mixed implicitly
Examples: Erlang, Python, Ruby, Common Lisp, Haskell, OCaml
Weak typing: Ignores type rules, types can be mixed implicitly
Examples: PHP, C, JavaScript
Static typing: Explicitly stating the types, variables can't change their type
Examples: C, C++, Haskell, C#, Java, Scala, OCaml
Dynamic typing: Types not stated, variables can change their types
Erlang, Python, Ruby, Common Lisp, Scheme
0 notes
electric-segfault · 9 years ago
Text
Why CLOS is the Coolest Object System Ever!
What's this? A blog post about OOP from a guy who obviously hates OOP? What's going on? D:
Let me tell you what's going on; cool tech so old it mostly falls under the radar.
Common Lisp Object System, as it's called, is about as old as object systems get, but that does not hurt it at all.
As with anything else in Common Lisp (CL), the object system is handled a little bit differently from most other languages. As an example, it's much more reminiscent of C's way of programming with structs and functions, in that it doesn't support the familiar dot notation of popular languages like Python, Ruby, C++, Java, or C#. But believe it or not, that actually works to its advantage.
A bit of background first in reading Lisp syntax if you're not familiar. A function call in Ruby/Python/C/etc goes like this:
foo(); // without arguments foo(a, b, c); // with arguments
In CL, or any other Lisp for that matter it's like this:
(foo) ; without arguments (foo a b c) ; with arguments
You can basically think of it as the parentheses going around the function name rather than at the end.
Cool Thing #1
CL supports multiple inheritance!
I can already hear the C++ programmers starting to cry in a corner having flashbacks of the diamond problem and all the nightmares that entails.
But fear not! CL gets around this in a clever little way. The order in which the classes are inherited defines the precedence of the inherited fields and methods.
So suppose we write this (... marks irrelevant code):
(defclass C (A B) ...) (defclass D (B A) ...)
Where both A and B define a field called data. C will inherit A's data field, while D will instead inherit B's.
Okay, granted multiple inheritance isn't all that impressive; Scala has it too via traits, and it works much the same way. But Scala is much newer than Common Lisp, so it wouldn't be unfair to suspect Scala got this mechanism from CL.
Cool Thing #2
CL doesn't use message passing, it uses generic functions!
"Okay, why does that make a difference?" I hear you say. It makes a tremendous difference actually, most of the awesome CLOS features are a result of this one decision.
Lisp used to have a Smalltalk-like method system working with message passing, but the issue with this is that it didn't integrate well with the way CL handles higher order functions. So to get around this, the creators of CLOS tried to make methods as function-like as possible so the user wouldn't have to worry about the implementational differences between the two and just use them.
To illustrate this important difference let me show you an example:
Say you have a method foo which you need to apply across every element in a list called lst. Using a send-like syntax like the one used in Racket, you'd need to do something like this:
(mapcar #'(lambda (x) (send x foo)) lst)
And now using generic functions instead of messages:
(mapcar #'foo lst)
Notation identical to as if foo was just a regular function.
But this isn't the only benefit of using generic functions over messages!
Cool Thing #2.1
Methods in CL aren't defined as part of a class!
You heard me right! Just like how functions aren't defined as part of structs/records in C and Haskell, methods aren't defined as part of your class.
What this means is basically that you can define a method to work with any existing class if you so desire. Users of C# and Objective-C are already familiar with this sort of concept, it's CL's equivalent of extension methods or category methods, except it goes a little bit beyond that, in that you can essentially put the method anywhere you want and start using it right away if you want to. Which means you don't need to define dedicated files just for extension methods, or a new file for each category just so you can extend the functionality of an existing class.
(defgeneric foo (a)) (defmethod foo ((a bar)) ...) (defmethod foo ((a number)) ...) (defmethod foo ((a string)) ...)
The example above defines a generic function foo which then implements three different overloaded methods, one acting on the bar class, and the other two acting on the built-in classes number and string no special hocus-pocus required.
This leads me to
Cool thing #2.2
Methods support dynamic multiple dispatching out of the box!
That's right, wave good bye to the annoying visitor pattern that plagues single dispatching. Due to the fact that methods aren't tied to any specific class right off the bat, and types are checked during runtime.
A classical example goes as follows (in pseudo-java/c#):
class A {} // implicitly extends Object void printObj(Object a) { print("'a' was of type 'Object'"); } void printObj(A a) { print("'a' was of type 'A'") } Object a = new A(); printObj(a);
Try to guess what text is going to be printed out... It's "'a' was of type 'Object'".
Despite the fact that a is an instance of A, it's still treated as an Object. This is fine for a lot of cases, but often if you have a lot of objects with a common super type that need to be dispatched on their concrete type, you'll need to whip out the visitor pattern, that checks the concrete type during runtime.
CL lets you extend this dispatching to as many arguments within a method as you please, essentially letting you be as specific as you please.
(defgeneric collide (obj1 obj2)) (defmethod collide (a b) (error "collision not defined for these objects")) (defmethod collide ((s ship) (a asteroid)) ...) (defmethod collide ((s1 ship) (s2 ship)) ...) (defmethod collide ((a asteroid) (s ship)) ...) (defmethod collide ((a1 asteroid) (a2 asteroid)) ...)
The example above gives a series of methods for a supposed space game, where objects can collide with each other, among these methods is one that takes any object at all and throws an error. Under a regular single dispatching system, if you had a list of random ships and asteroids, you'd get nothing but errors, since they'd all just be unspecific objects; but in a multiple dispatching system, all of these methods would be called correctly, only resulting in an error if something that isn't an asteroid or space ship slipped into the list of collision objects.
Cool Thing #3
(call-next-method)
CL lets you call the next-most relevant method with the same arguments as the current method from within. Think of it as calling the base-class' method with the same arguments, but automatic, and properly dispatched.
(defgeneric print-obj (o)) (defmethod print-obj (o) (print "received an object o")) (defmethod print-obj ((s string)) (print "received a string with the message") (print s) (call-next-method))
If print-obj receives a string it'll execute its own body, and then it'll run call-next-method which calls the general print-obj which works on any object. If however, print-obj receives an object that isn't a string, it'll just print "received an object o" and do nothing else.
Cool Thing #4
Method Qualifiers!
Perhaps the coolest thing about CLOS methods, is their qualifiers.
The condensed version is that you can add :before, :around, and :after to any method, which will affect the order of evaluation.
Say you have some code you always need to run after you finish some routine, instead of explicitly calling that code at the end of every method you define, you can instead do this:
(defgeneric db-connect (db obj)) (defmethod db-connect (db obj) ;; act on the database ) (defmethod db-connect :before (db obj) ;; connect to the database ) (defmethod db-connect :after (db obj) ;; cleanup code goes here )
Because the :after method is defined it'll always run the cleaning routine after any primary method (method without qualifier) is done running, and since the :after method is defined as not taking any specific type, it'll always run regardless of what the primary method gets dispatched to.
:before works exactly like :after except it runs code before the primary method, rathe than after. In the above example, this could be used to open a database connection independently of the acting code.
:around is different. It requires the use of (call-next-method), but unlike the regular use of (call-next-method) execution returns to the :around method, so that more stuff can be done.
(defgeneric move (ship dest)) (defmethod move ((ship ship) (dest planet)) ;; do stuff related to landing on a planet here ) (defmethod move ((ship ship) (dest station)) ;; do stuff related to landing on a station here ) (defmethod move :around ((ship ship) dest) ;; calculate fuel remaining (if (>= fuel 0) ; if remaining fuel after trip is ≥ 0 (call-next-method) ; call primary method (warn "Not enough fuel, going nowhere.")) ; else warn player ;; print info about destination and fuel used )
All of this just scratches the surface of what the CLOS can do, and I won't even begin to go into the Meta-Object Protocol.
Yes, CLOS is super alien looking and it has some strange features, but those features can lead to creative and elegant solutions to problems that just wouldn't be possible in "traditional" object systems. Everything from dynamic multiple dispatching to qualifiers offer "new" and interesting extensions to the classical object model.
I can recommend reading the two chapters regarding OOP in Practical Common Lisp:
Object Reorientation: Classes
Object Reorientation: Generic Functions
0 notes
electric-segfault · 9 years ago
Text
Predicate-Oriented Programming
... Or whatever you might call it.
I played around in Erlang the other day, and got intrigued by the way it handles function guards, namely by having a when clause, that could be used for type-checking despite the fact that Erlang itself is a dynamically typed language.
Observe following:
multiply(a, b) when is_number(a) andalso is_number(b) -> a * b.
What this code essentially does, is guard against inputs that aren't numbers. One could of course just define it as such: multiply(a, b) -> a * b., but in doing so there wouldn't be anything preventing the user from calling the function with strings, a-la multiply("hello", "world")., which would of course result in an error.
Erlang, unfortunately, does not allow user-made functions to reside within guards, only built-in predicates and boolean expressions are allowed there.
That got me thinking though. What would happen if you were to make a programming language, that instead of a traditional type system used predicates?
Picture this for a moment: You could have functions and data with far more specific types than otherwise possible with traditional type systems. I can't speak for dependent typing, I'm not too familiar with that.
Example in pseudo code:
function make_odd(even x) returns odd = x + 1. function make_name(capital fst, capital lst) returns string = lst + ", " + fst.
So what's going on here? Simple.
In the make_odd example, we have a function that only accepts even numbers, and adds 1 to it to return an odd number. Both types are a predicate, so the compiler/interpreter will check to see if both the input and output adhere to their respective predicates.
In the second example, make_name, capitalised strings are expected as input, meaning "anna", "ANNA", "aNNA" will all fail, but only "Anna" will be accepted, because only the first letter is upper-case, thus making it a properly cased name. The output could itself be a special predicate, but in this case a simple string is chosen as the output to illustrate the fact that "normal" types would be a thing also.
The whole schtick in this, is the fact that users would be able to define their own predicates also. So say for example they defined a function for HTML called is_anchor_tag, the is_ portion could be stripped away when used in "type-mode", so a function like this could be defined:
function get_link(anchor_tag a) returns url = ???.
This would be functionally equivalent to doing this:
function get_link(string a) returns url = if is_anchor_tag(a) then ???.
A practical upshot of this, is that these predicates could essentially be used at compile-time, to then later reduce some overhead at run-time; or alternatively it could just be interpreted and used as actual predicates during run-time.
Interfaces in the object-oriented sense could also easily be defined like this, by writing a predicate that checks if a record contains specific fields. Then it doesn't matter what record is put in, so long as it has the correct fields it's all a-ok.
I guess that's just a random thought I had that I wanted to share with the interwebs, let me know what you think about it.
2 notes · View notes
electric-segfault · 9 years ago
Text
Things I’ve learned in my years writing OOP code
"Object Oriented Design Patterns" only exist to get around limitations within OOP.
Use Composition over Inheritance is something many experienced programmers will tell you, despite the fact that inheritance is OOP's strongest selling point
OOP doesn't scale... At all. Despite the fact that OOP is designed with more code-reuse in mind; 99% of the time, the code you write will only ever be used within the context of that one project you're working on. Not only that, but if your customer suddnly wants a change in the program, major sections need to be rewritten, because none of the code is compatible with said change. If you then were to ever extrapolate and generalise said code for a library it would either be impossible or take weeks to do so.
Implicit state is something carried around throughout all of your code whether you like it or not. It's like asking for a cup of coffee, but what you got was the Starbucks serving the coffee and the surrounding city bloc.
Reference Hell -- A place you go after having to carry the same object through 18 consecutive method calls, returning a new object with the new state only to realise the original object was changed too.
0 notes
electric-segfault · 10 years ago
Text
Languages in a Nutshell
C: Write a few functions that all do an OK job and call it a program.
Haskell: Write a ton of small functions that each do just one thing, then chain them ALL together using a bit of Category Theory, Type Theory and Magic, and call that a program.
Erlang: Write a lot of small functions that work great using the actor system, an alternative to traditional concurrency.
Java & C#: NEED MORE CLASSES!!!
Scala: Chill Java, I got this I learned some tricks from Haskell and Erlang, and they're gonna blow your mind!
Lisp: These were your father's parentheses, elegant weapons for a more... Civilized age
1 note · View note
electric-segfault · 10 years ago
Text
GRAND OPENING!
WauSoft Interactive has its grand opening! Or more accurately, the domain wausoft.eu actually points somewhere for a change (it’s crazy, I know)
It’s by no means the final version of the site, but it’s a step in the right direction.
2 notes · View notes
electric-segfault · 11 years ago
Photo
Tumblr media
made an ansi table cheat-sheet for anyone to use
1 note · View note
electric-segfault · 11 years ago
Link
First rule of reading anything: if a headline is an interrogative, the answer is a resounding 'no'. This might be the one exception to that rule. This Kickstarter is actually fairly interesting. No...
I'm not gonna say I called it, but yeah... I called it
2 notes · View notes
electric-segfault · 11 years ago
Text
Shutdown Patterns in Akka 2
I’ve seen a question pop up a number of times on the Akka Mailing List that looks something like: "How do you tell Akka to shut down the ActorSystem when everything’s finished?" It turns out that there’s no magical flag for this, no configuration setting, no special callback you can register for, and neither will the illustrious shutdown fairy grace your application with her glorious presence at that perfect moment. She’s just plain mean.
In this post, we’ll discuss why this is the case and provide you with a simple option for shutting down “at the right time”, as well as a not-so-simple-option for doing the exact same thing.
Read More
6 notes · View notes
electric-segfault · 11 years ago
Link
A lot has happened since the previous Pixel Shift post. Most notably, Google announced an all new design guideline called Material Design. Since the announcement, I’ve spent an insane amount of time pouring over all the new documentation to learn about every new, little detail as possible.
With...
70 notes · View notes
electric-segfault · 11 years ago
Link
A simple bit of extension methods that lets you write "someFolder" / "otherFolder" / "LastFolder" to create a java.io.File with that kind of path - Gist is a simple way to share snippets of text and code with others.
I made this a little while ago if anyone's interested, it reduces a lot of boilerplate and works like a charm
0 notes
electric-segfault · 11 years ago
Text
I have a very strong love/hate relationship with jQuery
.
0 notes
electric-segfault · 11 years ago
Photo
Tumblr media
"Project Funnel" is coming along nicely
0 notes
electric-segfault · 11 years ago
Video
youtube
I accidentally a thing
0 notes