"break"? What is this you speak of?



  • @Ben L. said:

    You think every computer has five megabytes of RAM and runs 70000 processes?

    That's not the point.

    The point is, why would you ("you" being the designer of Go) *disable* the ability to de-dupe memory, while also removing the ability to link 3rd party code? It's a lose-lose situation. Why would you do that?

    Anyway, remember when we were talking about the computer running thousands of web server threads? A web server is one place where you BADLY want to let the MMU do its de-dupe thang.



  • @blakeyrat said:

    Anyway, remember when we were talking about the computer running thousands of web server threads? A web server is one place where you BADLY want to let the MMU do its de-dupe thang.

    Hey everyone! In blakeyworld, threads require a full copy of the application and serving 20000 requests per second on a Core 2 Duo with 3GB of system RAM that is also running two Source Dedicated Server instances isn't possible. Well guess what. This is the real world where threads don't copy anything for no reason and the second part is what I JUST FUCKING DID.



  • @Ben L. said:

    Hey everyone! In blakeyworld, threads require a full copy of the application and serving 20000 requests per second on a Core 2 Duo with 3GB of system RAM that is also running two Source Dedicated Server instances isn't possible. Well guess what. This is the real world where threads don't copy anything for no reason and the second part is what I JUST FUCKING DID.

    Can anybody else parse that little paragraph?



  • @Ben L. said:

    i dont get it

    You think every computer has five megabytes of RAM and runs 70000 processes?

    What? No, where did you get that shit? Besides, we're not talking about the fucking runtime here, we're talking about libraries. You know, those things that useful languages have in spades? Those things that Go requires you to have the source to compile against? That Go makes a copy of for every single program that uses them?



  • @Ben L. said:

    ...serving 20000 requests per second on a Core 2 Duo with 3GB of system RAM that is also running two Source Dedicated Server instances isn't possible.

    20k reqs/sec? Is Source Dedicated Server some kind of monster or something? 20k reqs/sec is pretty pitiful, really.



  • @blakeyrat said:

    @Ben L. said:
    Hey everyone! In blakeyworld, threads require a full copy of the application and serving 20000 requests per second on a Core 2 Duo with 3GB of system RAM that is also running two Source Dedicated Server instances isn't possible. Well guess what. This is the real world where threads don't copy anything for no reason and the second part is what I JUST FUCKING DID.

    Can anybody else parse that little paragraph?

    Wasn't the Source Dedicated Server that thing from The Matrix that Neo was trying to get? Not the real Matrix, mind you, but the sequels where they ruined everything and which were only made so that one Wachowski could afford his dick-removal surgery.



  • @morbiuswilters said:

    @blakeyrat said:
    @Ben L. said:
    Hey everyone! In blakeyworld, threads require a full copy of the application and serving 20000 requests per second on a Core 2 Duo with 3GB of system RAM that is also running two Source Dedicated Server instances isn't possible. Well guess what. This is the real world where threads don't copy anything for no reason and the second part is what I JUST FUCKING DID.

    Can anybody else parse that little paragraph?

    Wasn't the Source Dedicated Server that thing from The Matrix that Neo was trying to get? Not the real Matrix, mind you, but the sequels where they ruined everything and which were only made so that one Wachowski could afford his dick-removal surgery.

    Assuming you're not joking: the AppIDs are 229830 and 232250.



  • Honestly static linking solves a lot of problems with libraries on Linux (mainly that you have to have a software repo manage everything so that you don't have software compiled against the wrong version of the library or in the wrong place), but it's also throwing the bathwater out with the baby.



  • @MiffTheFox said:

    but it's also throwing the bathwater out with the baby.

    Why would you throw out perfectly good bathwater?



  • @Ben L. said:


    The type interface{} is "any value with a method set that is a superset of the empty set". That's useful in the same cases java.util.Object and C#'s object are useful. For example, fmt.Print accepts any value and prints it to stdout. reflect.ValueOf allows yo to look at the properties of any value. map[string]interface{} is roughly equivelent to a JSON object.

    Ah, I see. The FAQ made it sound like you could have multiple, somehow different empty interfaces, which made me think of Java's marker interfaces. (without the marker part... and the interface part...) But I guess if you have no type hierarchy but still need some kind of root type, defining it in terms of interfaces could be reasonable.




    @morbiuswilters said:
    So Go doesn't support any dynamic linking? (So it doesn't even support plugins as your original comment incorrectly implied..) Wow, Jesus, great fucking systems language there.

    You know, we joke about the Go designers being 40 years behind the times, but static linking?? A feature so out-of-date it's not even supported anymore in C: The Language That Supports More Ill-Conceived Shit From the 70s Than A George McGovern Rally???

    What worries me more is that it seems less an oversight/feature deferred to later versions than a dedicated opinion of the Go team. I don't have the time to find the original source, but this implies that the Go developers apparently consider dynamic linking harmful. Writing a plugin architecture in Go is a known open problem.

    This seems to be oddly in line with other Google-designed programming frameworks. If the Dart and the Chrome extension API are any indication, I bet if you asked the Go developers how to write a plugin, you'd get "write them as a separate process and communicate via stdout/sockets/plain text files/morse code" as an answer. For efficiency. And, "you know, in most cases, you don't really need plugins anyway".


    (That is, DSLs are an awesome thing and I'd be perfectly fine with Go restricting itself to a set of clearly-defined use-cases and leaving out other features because they are out of scope. But where are the use cases for Go?)



  • @PSWorx said:

    (That is, DSLs are an awesome thing and I'd be perfectly fine with Go restricting itself to a set of clearly-defined use-cases and leaving out other features because they are out of scope. But where are the use cases for Go?)

    IIRC Google only wrote Go for a specific task on their indexing servers the web and then decided to release it because "hey why not". I'm not entirely sure what it does at Google, maybe the map part of a map-reduce thingy?



  • @MiffTheFox said:

    IIRC Google only wrote Go for a specific task on their indexing servers the web and then decided to release it because "hey why not". I'm not entirely sure what it does at Google, maybe the map part of a map-reduce thingy?

    Read-between-the-lines translation: one of their engineers went rogue and spent years building this bullshit instead of actually doing his assigned task in Ruby or Python (or even C++) in 1/10th the time.



  • @blakeyrat said:

    @MiffTheFox said:
    IIRC Google only wrote Go for a specific task on their indexing servers the web and then decided to release it because "hey why not". I'm not entirely sure what it does at Google, maybe the map part of a map-reduce thingy?

    I do not understand anything you just said so I'm going to default to making fun of Go.


    FTFblakey



  • @MiffTheFox said:

    I'm not entirely sure what it does at Google, maybe the map part of a map-reduce thingy?

    I think it's the core of that Google product that isn't search or ads. You know, the one that was an unprofitable failure until management pulled the plug?



  • @bardofspoons42 said:

    On a whim, I ran NDepend against the wonderful code base that exists here, to see what sort of thing it would find (Methods with 13 parameters, several constructors with well over 100 lines of code, a class with 123 instance methods, another with 153 static methods). Looking into one of the methods it reported on (due to a large number of local variables), I spotted this:

    while (_dataReader.Read() && _listCount <= _recipientLimit)
    {
    	if (_listCount == _recipientLimit)
    	{
    		_listWithinLimits = false;
    		_listCount++; //This gets us out of the loop.
    	}
    	else
    	{
    		//Other stuff
    	}
    }
    

    I should also note that the underscore prefixed variables are locals, and not instance variables. Words escape me.

    At least he didn't try to get out of the loop by throwing an exception and wrapping the loop in a try...catch.

    Yes, I've seen that before. And not because something had an error, but as part of a normal and expected termination condition of the loop.



  • @blakeyrat said:

    DOM was designed to interface with *any* programming language that might someday be used in a browser. So far that's consisted of exactly 2 languages: JavaScript and ActiveX. And ActiveX is dead.
    Right on the DOM, wrong on the interfaces.  Not helping your credibility any.

    First, ActiveX is not a language, it is a plugin architecture to be utilized by any language.  ActiveX is still how you plug-in to IE on Windows for Flash, etc. 

    Secondly, there were other scripting languages, such as VBScript, but the lack of baked-in support cross browser killed it off... which would be Firefox as there was quite a bit still out there while IE was "the" browser being used.  There has also been PerlScript, and possible tcl, though I think that never made it into a released browser.

     @blakeyrat said:

    The JRE is part of "Java-the-stack", it's not part of "Java-the-language".

    @MiffTheFox said:

    As for JavaScript having real OO,

    JS has real OO, unless you're redefining the term "object orientation" to something other than the common usage.

    JS does not have inheritance. Inheritance is not required to be OO.

    Using that definition, VB6 was Object Oriented... I really do not want to get back into that decade 1/2 old argument again.

  • Considered Harmful

    @dhromed said:

    @morbiuswilters said:

    "dhromed's best birthday ever!"

     

    A stunning conclusion!

     

    The answer is, of course, to not use inheritance in javascript. If you need inheritance, your application has clearly outgrown its scripty nature.

    I invoke the dark arts of necromancy to announce that, after reading the excellent Effective Javascript, I have developed a pattern that solves the problems in prototypal inheritance without any hacks, in ECMAScript 5. (ECMAScript 6 apparently will have actual classes, which I'm dubious about.)

    First, let's go over some of the problems and failed solutions:

    1. Derived classes share a single prototype, making all inherited properties behave as static

      To illustrate:

      <html><body style='color:#000000; background:#ffffff; '>
      function Foo() {
          this.arr = [];
      }
      function Bar() {}
      Bar.prototype = new Foo;
      var bar1 = new Bar, bar2 = new Bar;
      bar1.arr.push( 1 ), bar2.arr.push( 2 );
      console.log( bar1.arr ); // expected: [1], actual: [1, 2]
      

    2. Modifying the prototype (by changing the prototype property of the constructor, or with the nonstandard __proto__ or the upcoming ES6 setPrototypeOf method) of an instance breaks the instanceof operator

      This technique felt borderline abusive to me, but it also suffers from a problem that was a dealbreaker for me. I was trying to implement Morbs' solution of calling the constructor without new, then changing the prototype of the constructor and returning a new instance. Several variations on this theme all revealed that after building multiple instances this way, the instanceof operator failed to work as intended.

      Example:

      <html><body style='color:#000000; background:#ffffff; '>
      function Foo() {}
      

      function Bar() {
      if( !( this instanceof Bar ) ) {
      Bar.prototype = new Foo;
      return new Bar;
      }

      }

      var bar1 = Bar(), bar2 = Bar();
      console.log( bar1 instanceof Foo ); // expected: true, actual: true
      console.log( bar1 instanceof Bar ); // expected: true, actual: false WTF!? (this makes much more sense after reading in-depth)
      console.log( bar2 instanceof Foo ); // expected: true, actual: true
      console.log( bar2 instanceof Bar ); // expected: true, actual: true

    3. Calling the base constructor results in duplication of properties/side-effects between prototype object and instance

      This (and 1) was suggested to be worked around with an initialize method, to be called after construction. This approach always struck me as unclean, as well as a bit brittle, as it requires an additional responsibility (always call initialize!); plus, I'm lazy. Why should I have to remember to do that? Not to mention it's a pain in the ass to properly cascade up multiple levels of inheritance.

    4. There's no analogy to the base (or super) keyword

      Sure, it looks like Object.getPrototypeOf( this ) has you covered, until you realize that this refers to the receiver of the function, which is going to be the most-derived class. If you try to pass a method up to multiple levels of inheritance, it's going to get stuck on the second-level forever.

    OK, problems I have many, but solutions I have 1. Note that I'm using AMD (RequireJS). Each class has its own file. I use the following pattern:

    <html><body style='color:#000000; background:#ffffff; '>
    ( function() { // IIFE to keep my variables from polluting global scope
        'use strict'; // always
    
    <span style='color:#800000; font-weight:bold; '>var</span> define <span style='color:#808030; '>=</span> this<span style='color:#808030; '>.</span>define<span style='color:#808030; '>,</span> require <span style='color:#808030; '>=</span> this<span style='color:#808030; '>.</span>require<span style='color:#800080; '>;</span> <span style='color:#696969; '>// AMD functions provided by RequireJS</span>
    
    define<span style='color:#808030; '>(</span> <span style='color:#808030; '>[</span> <span style='color:#0000e6; '>'MyBase'</span> <span style='color:#808030; '>]</span><span style='color:#808030; '>,</span> <span style='color:#800000; font-weight:bold; '>function</span><span style='color:#808030; '>(</span> MyBase <span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span> <span style='color:#696969; '>// dependencies injected with AMD</span>
        <span style='color:#696969; '>// aliasing everything to generic variable names make this easier to template/copypasta</span>
        
        <span style='color:#800000; font-weight:bold; '>var</span> foo<span style='color:#800080; '>;</span> <span style='color:#696969; '>// private shared/"static" variable</span>
        
        <span style='color:#800000; font-weight:bold; '>var</span> ctor <span style='color:#808030; '>=</span> <span style='color:#800000; font-weight:bold; '>function</span> MyDerived<span style='color:#808030; '>(</span><span style='color:#808030; '>)</span> <span style='color:#800080; '>{</span>
            baseCtor<span style='color:#808030; '>.</span>call<span style='color:#808030; '>(</span> <span style='color:#800000; font-weight:bold; '>this</span> <span style='color:#808030; '>)</span><span style='color:#800080; '>;</span> <span style='color:#696969; '>// call base constructor</span>
            
            <span style='color:#800000; font-weight:bold; '>var</span> bar<span style='color:#800080; '>;</span> <span style='color:#696969; '>// private instance variable</span>
            
            <span style='color:#797997; '>Object</span><span style='color:#808030; '>.</span>defineProperties<span style='color:#808030; '>(</span> <span style='color:#800000; font-weight:bold; '>this</span><span style='color:#808030; '>,</span> <span style='color:#800080; '>{</span> <span style='color:#696969; '>/* instance property descriptors go here */</span> <span style='color:#800080; '>}</span> <span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
        <span style='color:#800080; '>}</span><span style='color:#808030; '>,</span>
        baseCtor <span style='color:#808030; '>=</span> MyBase<span style='color:#808030; '>,</span> <span style='color:#696969; '>// parent constructor, fetched with AMD</span>
        base <span style='color:#808030; '>=</span> baseCtor<span style='color:#808030; '>.</span><span style='color:#797997; '>prototype</span><span style='color:#808030; '>,</span> <span style='color:#696969; '>// use this one to bubble methods up</span>
        proto <span style='color:#808030; '>=</span> ctor<span style='color:#808030; '>.</span><span style='color:#797997; '>prototype</span> <span style='color:#808030; '>=</span> <span style='color:#797997; '>Object</span><span style='color:#808030; '>.</span>create<span style='color:#808030; '>(</span> base<span style='color:#808030; '>,</span> <span style='color:#696969; '>// this is the real magic</span>
            <span style='color:#696969; '>// We make the prototype a new object with the same prototype as</span>
            <span style='color:#696969; '>// the base constructor, instead of an instance of the base constructor,</span>
            <span style='color:#696969; '>// we avoid the multiple constructor call/duplication of properties problem.</span>
            <span style='color:#800080; '>{</span> <span style='color:#696969; '>/* shared/"static" property descriptors (including methods) go here */</span> <span style='color:#800080; '>}</span>                       
        <span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
        
    
        <span style='color:#800000; font-weight:bold; '>return</span> ctor<span style='color:#800080; '>;</span> <span style='color:#696969; '>// or "return new ctor" for a singleton</span>
    <span style='color:#800080; '>}</span> <span style='color:#808030; '>)</span><span style='color:#800080; '>;</span>
    

    }() );


    This solves all 4 major issues above, and it does so without any dirty hacks or trickery. The instanceof operator works exactly how it should; each constructor in the prototype chain is called exactly once for each instance; instances can derive properties that aren't shared with other instances (but can share them if they so choose); you don't have to remember to avoid new or call initialize; you can call methods of the base class from anywhere in the prototype chain; and there's no usage of non-standard features. The only real drawback it's ES5, so ancient browsers might have some trouble. Since I'm working on an HTML5 canvas game, this is not a concern for me.

    I hope this helps someone, I beat my head on this for most of a week! Also, can't recommend the book I linked in my introduction sentence enough.

    (Edit: this damn source formatter outputs some bullshit broken markup)


  • Discourse touched me in a no-no place

    So… does it do multiple inheritance yet? The only truly tricky bit with MI is how to resolve the diamond inheritance problem, and that was definitively solved back in the '90s.



  • @ArrivingRaptor said:

    And that ++ there isn't doing anyone any favors.
    People say that a lot about C++



  • @El_Heffe said:

    @ArrivingRaptor said:

    And that ++ there isn't doing anyone any favors.
    People say that a lot about C++

    user@ubuntu:~/bicrement$ cat main.cpp
    #include <iostream>
    
    int main() {
            int x = 0;
            (++x)++;
            std::cout << x << std::endl;
    
            return 0;
    }
    user@ubuntu:~/bicrement$ g++ -Wall main.cpp 
    user@ubuntu:~/bicrement$ ./a.out 
    2
    

  • Discourse touched me in a no-no place

    @Ben L. said:

    user@ubuntu:~/bicrement$ cat main.cpp
    #include <iostream>

    int main() {
    int x = 0;
    (++x)++;
    std::cout << x << std::endl;

        <span style="color:#800000;font-weight:bold;">return</span> <span style="color:#008c00;">0</span><span style="color:#800080;">;</span>
    

    }
    user@ubuntu:~/bicrement$ g++ -Wall main.cpp
    user@ubuntu:~/bicrement$ ./a.out
    2

    I'm fairly certain that's undefined behaviour you have there and it is, therefore, not guaranteed to output 2.


  • Discourse touched me in a no-no place

    @PJH said:

    I'm fairly certain that's undefined behaviour you have there and it is, therefore, not guaranteed to output 2.
    I think it's OK in this case, because the post-increment is applied to the result of the pre-increment.

    Awful code smell though. Refactor.


  • Discourse touched me in a no-no place

    @dkf said:

    @PJH said:
    I'm fairly certain that's undefined behaviour you have there and it is, therefore, not guaranteed to output 2.
    I think it's OK in this case, because the post-increment is applied to the result of the pre-increment.

    Awful code smell though. Refactor.

    It's modifying x twice between sequence points; it's undefined behaviour.



  • @PJH said:

    @dkf said:
    @PJH said:
    I'm fairly certain that's undefined behaviour you have there and it is, therefore, not guaranteed to output 2.
    I think it's OK in this case, because the post-increment is applied to the result of the pre-increment.

    Awful code smell though. Refactor.

    It's modifying x twice between sequence points; it's undefined behaviour.
    Bug report: the bicrement operator makes demons come out of my nose

    Closed: WONTFIX: nasal demons are by design


  • Discourse touched me in a no-no place

    @PJH said:

    It's modifying x twice between sequence points; it's undefined behaviour.
    Umm, no. Not in this case. The argument to the post-increment is specifically the result of the pre-increment (necessarily so, because of the parentheses) and function calls (which operators are a funny syntax for, at least in C++) are sequence points. It's all well-defined.

    It can't be C or Java, as with those languages the result of either pre- or post-increment there is an r-value and the increments can only be applied to l-values.


Log in to reply