Reverse functional programming



  • From #go-nuts on freenode:

    19:36 < dsal> I've not seen this style of programming before.
    19:36 < dsal> It's sort of the opposite of functional.
    19:36 < dsal> Like, "must never return something, all parameters must be modified in place"
    
    package main
    
    import (
    	"fmt"
    	"math"
    	"math/rand"
    	"runtime"
    	"time"
    )
    
    // Computes the element-wise squared distance between two
    // slices. Returns a slice where the value at element i is
    // equal to (input[i] - output[i])^2
    func ElemSqDist(input, output, ans []]float64) {
    	for i, val := range input {
    		ans[i] += math.Pow(val-output[i], 2)
    	}
    }
    
    // Computes the element-wise average of the element-wise
    // squared distance between two slice of slices
    func TotalSqDist(inputs, outputs []][]]float64, totalSqDist []]float64) {
    	for i := range inputs[0] {
    		totalSqDist[i] = 0
    	}
    	for i := range inputs {
    		ElemSqDist(inputs[i], outputs[i], totalSqDist)
    	}
    }
    
    type DataSet struct {
    	inputs  []][]]float64
    	outputs []][]]float64
    	sqDist  []]float64
    }
    
    func CreateDatasets(nWorkers, nDim int) []]*DataSet {
    
    	datasets := make([]]*DataSet, nWorkers)
    	for i := range datasets {
    		datasets[i] = &DataSet{sqDist: make([]]float64, nDim)}
    	}
    	return datasets
    }
    
    func LaunchWorkers(nWorkers int, compute func(*DataSet)) (chan *DataSet, chan *DataSet, chan bool) {
    
    	inputCh := make(chan *DataSet, nWorkers)
    	resultCh := make(chan *DataSet, nWorkers)
    	quitCh := make(chan bool)
    	for i := 0; i < nWorkers; i++ {
    		go func() {
    			for {
    				select {
    				case d := <-inputCh:
    					compute(d)
    					resultCh <- d
    				case <-quitCh:
    					return
    				}
    			}
    		}()
    	}
    	return inputCh, resultCh, quitCh
    }
    
    func CloseWorkers(inputCh, resultCh chan *DataSet, quitCh chan bool) {
    	close(quitCh)
    }
    
    // Compute the total squared error in parallel.
    func ParTotalSqDist(inputs, outputs []][]]float64, totalSqDist []]float64, nWorkers, chunkSize int, datasets []]*DataSet, inputCh, resultCh chan *DataSet) {
    
    	for i := range inputs[0] {
    		totalSqDist[i] = 0
    	}
    
    	// Function closure for sending data
    	SendChunk := func(minIndex, maxIndex int, d *DataSet) {
    		d.inputs = inputs[minIndex:maxIndex]
    		d.outputs = outputs[minIndex:maxIndex]
    		inputCh <- d
    	}
    	// Function closure for receiving data
    	ReceiveChunk := func(totalSqDist []]float64) *DataSet {
    		d := <-resultCh
    		for i, val := range d.sqDist {
    			totalSqDist[i] += val
    		}
    		return d
    	}
    
    	idx := 0
    	// Send out the first set of chunks to the Workers
    	var totalSent int
    	for totalSent = 0; totalSent < nWorkers; totalSent++ {
    		minIndex := idx
    		maxIndex := idx + chunkSize
    		idx += chunkSize
    		if maxIndex > len(inputs) {
    			maxIndex = len(inputs)
    		}
    		SendChunk(minIndex, maxIndex, datasets[totalSent])
    		if idx >= len(inputs) {
    			break
    		}
    	}
    	// Send out next sets of chunks to the Workers
    	for {
    		if idx >= len(inputs) {
    			break
    		}
    		d := ReceiveChunk(totalSqDist)
    		minIndex := idx
    		maxIndex := idx + chunkSize
    		idx += chunkSize
    		if maxIndex > len(inputs) {
    			maxIndex = len(inputs)
    		}
    		SendChunk(minIndex, maxIndex, d)
    	}
    	// Receive the last set of results
    	for i := 0; i < totalSent; i++ {
    		_ = ReceiveChunk(totalSqDist)
    	}
    }
    
    func RandomSliceOfSlice(nSamples, nDim int) (sos []][]]float64) {
    	sos = make([]][]]float64, nSamples)
    	for i := range sos {
    		sos[i] = make([]]float64, nDim)
    		for j := range sos[i] {
    			sos[i][j] = rand.Float64() * float64(j+1)
    		}
    	}
    	return sos
    }
    
    func main() {
    	runtime.GOMAXPROCS(runtime.NumCPU())
    	nSamples := 100000
    	nDim := 500
    	nRuns := 5
    	chunkSize := 100
    
    	runtimes := make([]]float64, nRuns)
    	answers := make([]]float64, nRuns)
    	inputs := RandomSliceOfSlice(nSamples, nDim)
    	outputs := RandomSliceOfSlice(nSamples, nDim)
    
    	// Create function closure for the workers
    	compute := func(d *DataSet) {
    		TotalSqDist(d.inputs, d.outputs, d.sqDist)
    	}
    
    	// Create memory and launch Workers
    	nWorkers := runtime.NumCPU()
    	datasets := CreateDatasets(nWorkers, nDim)
    	inputCh, resultCh, quitCh := LaunchWorkers(nWorkers, compute)
    
    	fmt.Println("Starting runs")
    	totalSqDist := make([]]float64, nDim)
    	tFirst := time.Now()
    	for i := 0; i < nRuns; i++ {
    		t := time.Now()
    		ParTotalSqDist(inputs, outputs, totalSqDist, nWorkers, chunkSize, datasets, inputCh, resultCh)
    		runtimes[i] = time.Since(t).Seconds()
    		answers[i] = totalSqDist[0]
    	}
    	fmt.Println("The total runtime is ", time.Since(tFirst).Seconds())
    	fmt.Println("The runs took \n", runtimes[:5], " \n seconds. The first elements of the answer are \n", answers[:5])
    	CloseWorkers(inputCh, resultCh, quitCh)
    	time.Sleep(time.Second)
    }
    


  • Can you point out the actual WTF instead of just pasting a hundred lines of hideous syntax?

    Is it because it returns by modifying a parameter passed-by-reference? Because that's not an uncommon paradigm in some languages.. you really haven't given us nearly enough information to comprehend what's going on without having to learn Go (and that's not gonna happen) and then parse all that crap.



  • @morbiuswilters said:

    Can you point out the actual WTF instead of just pasting a hundred lines of hideous syntax?

    Seriously. Quantity is not the same as quality. And that font is tiny. (Yes, I know it's the default CS monospace font, it's still fucking tiny and unreadable.)

    @morbiuswilters said:

    Is it because it returns by modifying a parameter passed-by-reference?

    I use "out" params pretty often in C#. But I'm a WTF so.



  • Agreed. Every bit of Go I've seen makes it out to be an unholy union of C, Python, and Erlang. I'm not learning that unless I have to for my job.



  • Okay, let me break this down:

    First, it allocates 800MB of memory and fills it with random floating point numbers.

    Then, it spawns a thread for each CPU, ignoring your environment variables and settings.

    Then it runs this little thing on each one:

    // Computes the element-wise squared distance between two
    // slices. Returns a slice where the value at element i is
    // equal to (input[i] - output[i])^2
    func ElemSqDist(input, output, ans []]float64) {
    	for i, val := range input {
    		ans[i] += math.Pow(val-output[i], 2)
    	}
    }
    
    That's right, it takes three slices (similar to what Java calls "arrays") as input and has no return value.

    That runtimes[:5] near the bottom means "give me the first 5 values of runtimes". In this context, it is basically "crash if nRuns is less than 5".

    		answers[i] = totalSqDist[0]

    Right here, it's taking the first element of totalSqDist (a 500-element slice) and just forgetting the rest of it existed. Because all those calculations needed to produce the other 499 useless numbers would go to waste if they were used anywhere.

    Right near the end, it calls this function:

    func CloseWorkers(inputCh, resultCh chan *DataSet, quitCh chan bool) {
    	close(quitCh)
    }
    
    It takes three arguments and calls another function on one of them and ignores the fact that the other ones were even passed in.

    And then it sleeps for 1 second. Because everyone knows you should allow at least 1 second for your processors to cool down before exiting. By the way, omitting the last two lines of main would make no difference in what the useless program does.



  • @Ben L. said:

    Then, it spawns a thread for each CPU, ignoring your environment variables and settings.

    What environment variable and/or setting dictates how many threads a program should create?

    @Ben L. said:

    Right here, it's taking the first element of totalSqDist (a 500-element slice) and just forgetting the rest of it existed. Because all those calculations needed to produce the other 499 useless numbers would go to waste if they were used anywhere.

    As far as I can tell, the only input to this program is tons of psuedo-random numbers. So... what makes the other 499 numbers somehow more useless than the first one? As far as I can tell from your description the entire program's useless.



  • @blakeyrat said:

    @Ben L. said:
    Right here, it's taking the first element of totalSqDist (a 500-element slice) and just forgetting the rest of it existed. Because all those calculations needed to produce the (other 499) (useless numbers) would go to waste if they were used anywhere.

    As far as I can tell, the only input to this program is tons of psuedo-random numbers. So... what makes the other 499 numbers somehow more useless than the first one? As far as I can tell from your description the entire program's useless.


    Parenthesized that for you



  • @Ben L. said:

    Parenthesized that for you

    Ok whatever, but in your entire summary you missed probably the most important point: what the holy fuck is this program supposed to do? Because right now it doesn't do shit. Which makes me think it was written solely to demo this (according to you) incorrect way of passing data to functions.



  • @arotenbe said:

    Agreed. Every bit of Go I've seen makes it out to be an unholy union of C, Python, and Erlang. I'm not learning that unless I have to for my job.


    Perhaps you should stop looking for good examples of languages on The Daily WTF.



  • @blakeyrat said:

    @Ben L. said:
    Parenthesized that for you

    Ok whatever, but in your entire summary you missed probably the most important point: what the holy fuck is this program supposed to do? Because right now it doesn't do shit. Which makes me think it was written solely to demo this (according to you) incorrect way of passing data to functions.

    Exactly. I don't know why this exists. I just seems like nonsense. Is this real code from a real application?



  • @Ben L. said:

    @arotenbe said:

    Agreed. Every bit of Go I've seen makes it out to be an unholy union of C, Python, and Erlang. I'm not learning that unless I have to for my job.


    Perhaps you should stop looking for good examples of languages on The Daily WTF.

    I don't think he said every bit of Go he's seen was on TDWTF. In fact, his complaints seem to be about the language itself, not the code example.

    Most of the Go I've ever seen made it look ludicrous, a mish-mash of other languages thrown together for no discernible reason. That includes the "easy threading" example you posted, which I still don't know if you were actually saying that was supposed to illustrate Go's threading or if you were being sarcastic.



  • @morbiuswilters said:

    Most of the Go I've ever seen made it look ludicrous, a mish-mash of other languages thrown together for no discernible reason.

    Exactly. Most programming languages have some kind of guiding principle at their core, which drives the entire direction of the language. Typically, you can sum up the entire language in a single sentence. C is like a high-level assembly language. Java is mindlessly object-oriented. Python is supposed to be really easy to read. Lisp turns everything into lists for metaprogramming purposes. Haskell is all about embedding other languages' features in a purely-functional environment. Even Perl seems to have a coherent goal of a sort: make a language that supports or can support every feature ever concieved by anyone.

    What the heck is Go?



  • I'm going to link to a FAQ entry that you are sure to ignore.



  • So the code you've posted is directly from the source for Go? Like a library or something? I'm trying, but like the other 2ish people posting on this thread, there's still barely enough context to make anything out here...



  • @arotenbe said:

    What the heck is Go?

    From what I can tell, it looks like someone had the idea to have language-level support for blocking queues specifically, then they grew concurrency over the top of that.
    Several iterations of unnatural* selection later, and it evolved into... whatever it is now.



  • @Ben L. said:

    I'm going to link to a FAQ entry that you are sure to ignore.

    Guys my computer has multiple cores. I am so worried and confused.



  • @Ben L. said:

    I'm going to link to a FAQ entry that you are sure to ignore.
    lol the faq has the same problem you have with not actually answering the question. The answer to whats the origin of the name is some gibberish about what would be a good name for a go debugger?

    the author of the FAQ seems to think Java is a systems language? WTF? I mean how can a language that complies to bytecode (not a native ASM) interpreted by a VM be used for systems programming. I don't think they mean the same thing as systems programming as the rest of the world.

    just a cursory glance at their FAQ makes me think these people have no idea what the fuck they are talking about.



  • @Ben L. said:

    I'm going to link to a FAQ entry that you are sure to ignore.

    This made me ROFL:

    @Go FAQ said:

    The emergence of multicore computers has generated worry and confusion.

    If that's the Go team's reaction to multi-processing, it explains a lot..

    So.. Go is a replacement for C, but without the primary reason people use C: the vast, vast base of existing libraries and code. That's like giving me a replacement for my car that lacks an engine, 4 wheels or seating for more than 1 person.

    Go seems like an answer to a question nobody asked. Okay, it's got improved compilation and dependency management than C, big whoop. It seems to lack most of the features of more advanced, OOP languages. It also lacks the raw performance and low-level power of C.

    Why did anybody make time creating this? Think of all the ditches these programmers could have dug if they weren't wasting time on this shit. Think of all of the boulders they could move from one pile to another pile, and then back again. They could work to calculate Pi to a billion places by hand. Shit, they could have played computer Solitaire. Anything seems like a better use of time and effort than creating yet another, marginal, hardly-used language that's not better at anything than existing languages.



  • @blakeyrat said:

    @Ben L. said:
    I'm going to link to a FAQ entry that you are sure to ignore.

    Guys my computer has multiple cores. I am so worried and confused.

    Oh, but think that Go doesn't have any serious deployments; oh no, sir, it's used at Google (just not by one of the only three Google products that don't hemorrhage money..):

    @Go FAQ said:

    Yes. There are now several Go programs deployed in production inside Google. A public example is the server behind http://golang.org. It's just the godoc document server running in a production configuration on Google App Engine.

    See? They run the Go documentation server on Go. I take back all of my criticisms, that's some serious dogfooding right there.

    Life-support systems? Billion dollar fighter jets? Financial systems that handle trillions of dollars each day? Pfft, son, right now there are no less than three production MUDs running on Go.



  • @Ben L. said:

    I'm going to link to a FAQ entry that you are sure to ignore.

    Having read said FAQ entry, I can now say I know what the project's goals are. I think that choosing that group of goals as the central principles around which a language was designed was probably a terrible idea, but at least know what the goals are.

    Actually, since we're in full language war mode in this thread now, how about a point-by-point deconstruction of the FAQ's rationale?

    @FAQ said:
    Computers are enormously quicker but software development is not faster.

    Brilliant insight there, don't you think? And no, software development is faster, due to better tools and more use of high-level languages.

    @FAQ said:
    It is possible to compile a large Go program in a few seconds on a single computer.

    Seriously, one of the primary goals is optimizing for compilation time? I mean, I know typical C and C++ projects take way too long to compile and link, but I would never think that a language first developed in 2007 would need to specify that as a project target.

    @FAQ said:
    Go is fully garbage-collected and provides fundamental support for concurrent execution and communication.

    If you're developing low-level systems software, you usually don't want automated GC for everything and opaque concurrency support; whereas, if you're developing application software, you'd use an actual high-level language and wouldn't be thinking about things like header files. What kind of program is best written in Go?

    @FAQ said:
    There is a growing rebellion against cumbersome type systems like those of Java and C++, pushing people towards dynamically typed languages such as Python and JavaScript.

    Actually, given that the only real complaint they have about Java is its horrendously redundant type annotations, I'm wondering if they had just never heard of Scala when they started the project.

    @FAQ said:
    And perhaps most radically, there is no type hierarchy: types just are, they don't have to announce their relationships.

    Congratulations! You've invented Haskell's type classes, only crappier. (Those were invented in 1988. They called them "concepts" before they threw them out of C++11.) Also, it's kind of sad that the notion of not having subtype polymorphism is considered a radical idea at this point.



  • @arotenbe said:

    Exactly. Most programming languages have some kind of guiding principle at their core, which drives the entire direction of the language. Typically, you can sum up the entire language in a single sentence. C is like a high-level assembly language. Java is mindlessly object-oriented. Python is supposed to be really easy to read. Lisp turns everything into lists for metaprogramming purposes. Haskell is all about embedding other languages' features in a purely-functional environment. Even Perl seems to have a coherent goal of a sort: make a language that supports or can support every feature ever concieved by anyone.

    F# is for people not allowed, or too scared, to leave the bastion of .NET in order to do functional programming...am I getting this? (I kid, but I've known a few people who really need to step outside their comfort zone once in awhile and get some air).



  • @arotenbe said:

    If you're developing low-level systems software, you usually don't want automated GC for everything and opaque concurrency support; whereas, if you're developing application software, you'd use an actual high-level language and wouldn't be thinking about things like header files.

    DING! DING! DING!

    It's similar to the core fault of C++: it's too low-level for anyone to want to develop applications in, but with high-level features that don't do well in systems programming. (Not to mention it's got every language feature every conceived of built on the foundation of C, a language with one of the poorest specifications ever. Oh, and Stroustrup is a Misery Vampire who feeds off the suffering of developers, so he decided shit like recursive templates were a must-have.)



  • @blakeyrat said:

    @Ben L. said:
    I'm going to link to a FAQ entry that you are sure to ignore.

    Guys my computer has multiple cores. I am so worried and confused.


    It's an emergence-y!



  • I have to wonder where you work that requires you to use Go. Obviously not Google because, despite developing Go, at least all their outward-facing crap is still Python and Java.



  • @MiffTheFox said:

    I have to wonder where you work that requires you to use Go. Obviously not Google because, despite developing Go, at least all their outward-facing crap is still Python and Java.

    I don't think he works anywhere. He's 17 years old, and just started looking at entrance to universities.



  • @MiffTheFox said:

    I have to wonder where you work that requires you to use Go.

    He's probably a gay furry who lives in a filthy cheap apartment while writing a failed clone of Furaffinity.

    Oh wait no, that was someone else...



  • @blakeyrat said:

    @MiffTheFox said:
    I have to wonder where you work that requires you to use Go.

    He's probably a gay furry who lives in a filthy cheap apartment while writing a failed clone of Furaffinity.

    Oh wait no, that was someone else...

    You?



  • @morbiuswilters said:

    Why did anybody make time creating this?

    I just read the effective go page, and I'm convinced that the whole thing was an april fools joke that got out of hand.
    Here are some of the highlights:

    • Automatic semicolon insertion, leading to:
    • Forced brace style
    • The output of the godoc (go's documentation tool) is plaintext, and it recommends using grep.
    • "the visibility of a name outside a package is determined by whether its first character is upper case". It does not elaborate further on this point.
    • Using a switch statement on an object's type, because interfaces are for losers.
    • Importing a package and not using it is a fatal compiler error
    • "To silence complaints about the unused imports, use a blank identifier to refer to a symbol from the imported package."
    • "A [blocking queue] can be used like a semaphore". Because semaphores, like interfaces, are for losers.
    • The syntax for exception handling is bizarrely complex, presumably to discourage you from using it because:
    • All errors are reported as a return value from the method. Like C, but with multiple return values instead of global variables.



  • Unless I've misread it (which, given its verbosity and the minuscule amount of time I've been prepared to spend, is quite possible) the program does a known, and fairly substantial, amount of work and outputs the time taken to do it.

    Looks like a benchmarking program to me. Not necessarily the best one ever produced, mind you, and with no clear indication of what it's trying to measure - but perhaps that was in the accompanying documentation that seems to have mysteriously gone missing.



  • @aihtdikh said:

    and i am about to overflow a signed byte
     

    Hot.

     

    What we have with Go is an experimental language that is never used in any serious implementation because it's ridiculous and because it's never used anywhere the makers never get practical feedback and keep on making it more ridiculous.

    It's like a mathematical function orbit that escapes to infinity.



  • @morbiuswilters said:

    @arotenbe said:
    If you're developing low-level systems software, you usually don't want automated GC for everything and opaque concurrency support; whereas, if you're developing application software, you'd use an actual high-level language and wouldn't be thinking about things like header files.

    DING! DING! DING!

    It's similar to the core fault of C++: it's too low-level for anyone to want to develop applications in, but with high-level features that don't do well in systems programming. (Not to mention it's got every language feature every conceived of built on the foundation of C, a language with one of the poorest specifications ever. Oh, and Stroustrup is a Misery Vampire who feeds off the suffering of developers, so he decided shit like recursive templates were a must-have.)

     

     Can I get a rant in that style about Java please? As a matter of fact, can I have a rant like this about every language - I'm gonna put them in a document and just copy-paste them in whenever anybody wants to discuss language features.



  • How does that package name visibility think work in a language without the concept of "capitalization"?

    Oh wait, let me guess, this language designed in 2007 only supports ASCII.



  • @blakeyrat said:

    Oh wait, let me guess, this language designed in 2007 only supports ASCII.
     

    No, but it's clear it only supports variables in ASCII.

     



  • @Soviut said:

    @arotenbe said:
    Exactly. Most programming languages have some kind of guiding principle at their core, which drives the entire direction of the language. Typically, you can sum up the entire language in a single sentence. C is like a high-level assembly language. Java is mindlessly object-oriented. Python is supposed to be really easy to read. Lisp turns everything into lists for metaprogramming purposes. Haskell is all about embedding other languages' features in a purely-functional environment. Even Perl seems to have a coherent goal of a sort: make a language that supports or can support every feature ever concieved by anyone.

    F# is for people not allowed, or too scared, to leave the bastion of .NET in order to do functional programming...am I getting this? (I kid, but I've known a few people who really need to step outside their comfort zone once in awhile and get some air).

    Ooh, let me try some of these!

    PHP is scripted C.

    C# is Java with less syntax cruft.

    Bash is a shell that wishes it were a programming language.

    JavaScript was designed completely by accident by five-ish different teams all trying to make different things.



  • @Salamander said:

    "the visibility of a name outside a package is determined by whether its first character is upper case". It does not elaborate further on this point.
     

    That appears to be its way of dealing with public/private.



  • @dhromed said:

    @Salamander said:

    "the visibility of a name outside a package is determined by whether its first character is upper case". It does not elaborate further on this point.
     

    That appears to be its way of dealing with public/private.

    In addition to the lack of elaboration to explain that, it also doesn't state the relation between caps and visible. it just states there is one. Is uppercase visible? Or lowercase? Guess and check!



  • @blakeyrat said:

    How does that package name visibility think work in a language without the concept of "capitalization"?

    Oh wait, let me guess, this language designed in 2007 only supports ASCII.

    People will be building ASCII-only languages, etc. for a long time. Go gives every indication of being a pile of high-purity dog excretum (a garbage-collected systems programming language?); but using ASCII is no reason at all to criticize anyone or anything. There are damned good reasons for using ASCII, not the least of which is the fact that two identical-looking Unicode strings can in fact have radically different encodings. This is kind of a bummer, especially for people who actually want to know what URL they're communicating with. Unless you're a linguist or something like that, the benefits of ASCII far outweigh those of Unicode.



    What I see in a lot of your more recent posts is someone who's made his decision and accumulated a disjointed set of talking points in support thereof.



  • This Go code seems to work for me:

    package main
    

    import "fmt"

    func main() {
    var 世界 = "Hello from Unicode!";
    fmt.Println(世界)
    }

    Although what I want to know is what the default visibility for a member starting with 世 is, and whether there's any way to override a default selection.



  • @dhromed said:

    @blakeyrat said:
    Oh wait, let me guess, this language designed in 2007 only supports ASCII.
    No, but it's clear it only supports variables in ASCII.

    So to clarify: no, but really yes.


  • ♿ (Parody)

    @blakeyrat said:

    @dhromed said:

    @Salamander said:

    "the visibility of a name outside a package is determined by whether its first character is upper case". It does not elaborate further on this point.
     

    That appears to be its way of dealing with public/private.

    In addition to the lack of elaboration to explain that, it also doesn't state the relation between caps and visible. it just states there is one. Is uppercase visible? Or lowercase? Guess and check!

    So, did you not actually bother reading before flaunting your ignorance, or are you really as illiterate as you appear?

    @TFL said:

    In Go, a name is exported if it begins with a capital letter.



  • @morbiuswilters said:

    So.. Go is a replacement for C, but without the primary reason people use C: the vast, vast base of existing libraries and code. That's like giving me a replacement for my car that lacks an engine, 4 wheels or seating for more than 1 person.

    Why did anybody make time creating this? Think of all the ditches these programmers could have dug if they weren't wasting time on this shit. Think of all of the boulders they could move from one pile to another pile, and then back again. They could work to calculate Pi to a billion places by hand. Shit, they could have played computer Solitaire. Anything seems like a better use of time and effort than creating yet another, marginal, hardly-used language that's not better at anything than existing languages.

    Oh morbs, how we've missed your concise analyses. blakey's good, but your critiques just have something special about them.

    As for C, I wouldn't say the specification is poor, just intentionally vague and leaves everything up to the compiler implementer. Then you get two compilers that implement the same poorly-defined feature in ways that make cross-compilation impossible. So you add a preprocessor to the language to provide compile guards and OH GOD KILL ME NOW


  • ♿ (Parody)

    @blakeyrat said:

    @dhromed said:
    @blakeyrat said:
    Oh wait, let me guess, this language designed in 2007 only supports ASCII.
    No, but it's clear it only supports variables in ASCII.

    So to clarify: no, but really yes.

    They say identifiers, must begin with a letter, which class includes unicode letters.

    So, to correctify, no.



  • @MiffTheFox said:

    This Go code seems to work for me:

    package main
    
    import "fmt"
    
    func main() {
        var 世界 = "Hello from Unicode!";
        fmt.Println(世界)
    }
    

    Although what I want to know is what the default visibility for a member starting with 世 is, and whether there's any way to override a default selection.

    In languages where there are no capital letters, you need to use a capital letter from another language as a prefix to exported variables. It's a documented kludge.


  • @Ben L. said:

    @MiffTheFox said:

    This Go code seems to work for me:

    package main
    
    import "fmt"
    
    func main() {
        var 世界 = "Hello from Unicode!";
        fmt.Println(世界)
    }
    

    Although what I want to know is what the default visibility for a member starting with 世 is, and whether there's any way to override a default selection.

    In languages where there are no capital letters, you need to use a capital letter from another language as a prefix to exported variables. It's a documented kludge.

    Who cares about any of this? I'd really like to see the real-world case for Unicode identifiers that isn't "they make my language seem better than [some other language]."



    I might add this topic to my interview script. Q: What do you think about Unicode identifiers? A: That sounds like a horrible idea that would send any decent programmer off job-hunting.


  • Discourse touched me in a no-no place

    @arotenbe said:

    @FAQ said:
    It is possible to compile a large Go program in a few seconds on a single computer.

    Actually, fast compilation times effect improved RAD, according to people who've gotten significant computer upgrades. If you work iteratively by making small code changes and recompiling, cutting compile time in half nearly doubles the number of code-compile-test-debug cycles.

    I'm not sure making up a new language is the best fix--I'd think it might make more sense to improve existing processes; for example, precompiled headers in C/C++ are the shiznit, even on semi-trivial projects. (I have a toy program that consists of a few thousand LOC in 20 or so source files, and PCH can shrink compile time from 30 seconds to about 3. There's no real benefit to this example, but to the extent it scales, it's pretty nice. Also, throwing more cores and the compilation is well-known to improve times.


  • Considered Harmful

    @bridget99 said:

    Q: What do you think about Unicode identifiers? A: That sounds like a horrible idea that would send any decent programmer off job-hunting.

    I. But. You're only supposed to spout incomprehensible and/or indefensible...


  • Discourse touched me in a no-no place

    @bridget99 said:

    Who cares about any of this? I'd really like to see the real-world case for Unicode identifiers that isn't "they make my language seem better than [some other language]."

    Being limited to ASCII is probably racist; after all, nearly everything else is.



  • @morbiuswilters said:

    @arotenbe said:
    If you're developing low-level systems software, you usually don't want automated GC for everything and opaque concurrency support; whereas, if you're developing application software, you'd use an actual high-level language and wouldn't be thinking about things like header files.

    DING! DING! DING!

    It's similar to the core fault of C++: it's too low-level for anyone to want to develop applications in, but with high-level features that don't do well in systems programming. (Not to mention it's got every language feature every conceived of built on the foundation of C, a language with one of the poorest specifications ever. Oh, and Stroustrup is a Misery Vampire who feeds off the suffering of developers, so he decided shit like recursive templates were a must-have.)

    Oh thank GOD it's not just me.

    I've always been confused by Go: I've heard it referred to as a systems programming language, but as far as I can make out it adds a bunch of features you don't want if you're doing systems programming (a runtime, concurrency at the language level, automatic garbage collection) and then removes a bunch of features that are useful in systems programming (pointer arithmetic, unbounded arrays). I wonder if it's even possible to implement a kernel in Go where the Go code isn't simply a bunch of wrappers around code written in assembly & C, and where the Go runtime & supporting code isn't larger than the rest of the kernel?



  • @fire2k said:

    Can I get a rant in that style about Java please?

    Sure: Java's syntax is so clean, it's aseptic. It makes up for this by requiring so much boilerplate to accomplish any non-trivial task that one wonders if javac thinks all developers are retarded. The workaround is to use an IDE which will write this boilerplate for you. Preferred ones are NetBeans--which will make you wonder if its developers have ever used an IDE before--and Eclipse, which will rape your memory manager and also make you wonder if its developers have ever used an IDE before. Using an IDE will also acquaint you with the Java GUI development standards: 1) no single thing should look like any other single thing from the host OS; 2) a dialog that opens in less than 5 seconds is a showstopping bug; 3) there is no rule 3.

    Its type system combines the ease and elegance of Algol 68 with the safety of C void pointers. Strict typing guarantees that every single type must explicitly define its relationship to every single type it is a subtype of. A dearth of metaprogramming features ensures this specificity is in vain. Generics "fixed" this by making type safety a function of a library's license agreement; I'm not sure even Richard Stallman could dream up something so asinine.

    Hotspot's garbage collector goes on strike more often than those of NYC. GC means that managing memory is no longer a requirement of the developer; instead it is the responsibility of the user. Trying to understand when or why the GC runs is like answering a Zen koan--whatever you declare is likely to be both right and wrong at the same time.

    @fire2k said:

    As a matter of fact, can I have a rant like this about every language...

    Ruby: Slow. C-style brace syntax abandoned for something that looks like it was intended for pre-schoolers. Optional parentheses in function calls plus punctuation at the end of function names makes me feel like I'm reading a Markov chain suicide note from the computer.

    PHP: Also slow. Features are often solid, on the third try. First try: feature copied from language X, done in hilariously shitty way. Second try: companies which have thousands invested in PHP (God only knows why) make their engineers redo the feature to be less stupid. Third try: companies which have millions invested in PHP (???) finally do it right, or as close to right as PHP's core will allow, which is still shockingly far from the mark. All three variants will exist simultaneously in PHP. Due to the fact that most PHP devs suffer from profound mental retardation, the worst variant will invariably be the most popular. Since PHP devs are the absolute dregs of the programming world, all third-party code is essentially useless, except as a cautionary tale to expectant Appalachian mothers showing what will happen if they don't lay off the moonshine.



  • @bridget99 said:

    ...not the least of which is the fact that two identical-looking Unicode strings can in fact have radically different encodings.

    Yes, this is stupid, but Unicode normalization has been the--excuse me--norm for a very long time. Stop whining.


Log in to reply