When you should use Go



  • @tufty said:

    Go coders find themselves writing again and again the same things from an ant's vantage point

    The Scala coolc is 13796 lines of Scala, not including the standard library or runtime. The Go coolc is 12558 lines, including the standard library and runtime. Both of these figures include comments and empty lines.

    Here's what the Scala coolc does for match expressions during the semantic analysis phase: (nothing was added to or removed from this code)

            check_expr(c.get_expr(),env);
            var vt : Symbol = c.get_expr().get_of_type();
            var cs : Cases = c.get_cases();
            var rt : Symbol = nothing_sym;
            var ei : CasesEnumeration = cs.elements();
            while (ei.hasNext()) {
              ei.next() match {
                case ci:Cbranch =>
                  var is : Symbol = ci.get_local_type();
                  if (is == null_sym)
                    if (symbol_name(ci.get_name()) == "null")
                      if (current_env.type_leq(is,vt)) ()
                      else err(ci, consym("Case not possible for ",vt).concat(": 'Null'"))
                    else err(ci,"'Null' cannot be explicitly checked for, use 'null'")
                  else if (is == nothing_sym) err(ci,"'Nothing' is not a legal case")
                  else class_table.lookup_class(is) match {
                    case null => err(ci,consym("Undeclared case class: ",is))
                    case cd:Cclass_decl => ci.set_case_of_class(cd);
                      if (current_env.type_leq(is,vt)) () else
                        if (current_env.type_leq(vt,is)) () else
                          err(ci,consym(consym("Case not possible for ",vt).concat(": "), is))
                  };
                  var done : Boolean = false;
                  var ej : CasesEnumeration = cs.elements();
                  while (!done) {
                    ej.next() match {
                      case cj:Cbranch =>
                        if (ci == cj) done = true
                        else if (if (is == null_sym) cj.get_local_type() == null_sym
                                 else current_env.type_leq(is,cj.get_local_type()))
                          { err(ci,consym("Case already covered: ",is));
                            done = true }
                        else ()
                    }
                  };
                  var newenv : Environment =
                    new SingleEnvironment(ci.get_name(),ci,env);
                  var ty : Symbol = check_expr(ci.get_expr(),newenv);
                  ci.set_case_of_type(ty);
                  rt = env.type_lub(rt,ty)
              }
            };
            rt
    

    Here's the Go version: (again, nothing added or removed)

    func (e *MatchExpr) semantIdentifiers(ctx *semCtx, ids semantIdentifiers) *Class {
    	left := e.Left.semantIdentifiers(ctx, ids)
    
    	possible := make(map[int]bool)
    	if left == nothingClass {
    		// no possible types
    	} else if left == nullClass {
    		// only Null is possible
    		possible[0] = true
    	} else {
    		if ctx.Lub(nullClass, left) == left {
    			// left is a nullable type
    			possible[0] = true
    		}
    		// left and all of left's children
    		for i := left.Order; i <= left.MaxOrder; i++ {
    			possible[i] = true
    		}
    		// and all of left's parents
    		for p := left.Extends.Type.Class; p != nativeClass; p = p.Extends.Type.Class {
    			possible[p.Order] = true
    		}
    	}
    
    	var ts []*Class
    	for _, c := range e.Cases {
    		ts = append(ts, c.semantIdentifiers(ctx, ids, e, possible))
    	}
    
    	return ctx.Lub(ts...)
    }
    
    func (a *Case) semantIdentifiers(ctx *semCtx, ids semantIdentifiers, m *MatchExpr, possible map[int]bool) *Class {
    	left := a.Type.Class
    	any := false
    
    	check := func(min, max int) {
    		for i := min; i <= max; i++ {
    			if possible[i] {
    				possible[i] = false
    				any = true
    			}
    		}
    	}
    
    	if left == nothingClass {
    		// there are no values of type Nothing
    	} else if left == nullClass {
    		// check if Null is possible
    		check(0, 0)
    	} else {
    		// left and all of left's children
    		check(left.Order, left.MaxOrder)
    	}
    
    	if !any {
    		ctx.Report(a.Type.Pos, "unreachable case for type "+a.Type.Name)
    	}
    
    	ids = append(ids, &semantIdentifier{
    		Name:   a.Name,
    		Type:   a.Type,
    		Object: m,
    	})
    
    	return a.Body.semantIdentifiers(ctx, ids)
    }
    

    I'll let you draw your own conclusion about which language is easier to understand and write code in.



  • It's C#.



  • USE DOG RESIDUE

    You use the DOG RESIDUE.

    https://www.riking.org/dogsong.html

    Your inventory is now full of DOG RESIDUE.



  • Would you recommend C# for web apps when it needs to run in a Linux server?
    Is Mono working well with ASP.NET, entities framework and the ASP.NET MVC things?



  • @ben_lubar said:

    I'll let you draw your own conclusion about which language is easier to understand and write code in.

    As I find neither of them particularly readable, and I write compilers for fun, I draw the conclusion that you're a shit coder.



  • @fbmac said:

    Would you recommend C# for web apps when it needs to run in a Linux server?

    A couple years ago, probably not.

    Now? It would depend on the database being used and the quality of the database library. For example, an app using MongoDB I'd say is fine, because their DB connector is pretty first-class. An app using MySQL, maybe less so. (I honestly don't know how good MySQL's connector is.)

    If your tools are there and of decent quality, then sure. Why not C#?

    @fbmac said:

    Is Mono working well with ASP.NET, entities framework and the ASP.NET MVC things?

    Mono's quickly transitioning to using the newly open sourced compiler, which'll make it virtually 100% compatible with everything C#, up to the absolute latest version. The days of saying "oh it's Mono, so limit yourself to .net 2.0 features" are gone. (EDIT: I should add but C# limited to .net 2.0 features is still WAY better than pretty much any other language.)

    The exception of course is all the OS-specific stuff in the Microsoft.XXX assemblies, but those assemblies are separated out SPECIFICALLY because they contain OS-specific stuff. So in practice it's not really an issue.


Log in to reply