Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

It's not JavaScript, it's UnityScript

Discussion in 'General Discussion' started by coderarity, Feb 3, 2012.

  1. squidbot

    squidbot

    Joined:
    Jan 4, 2011
    Posts:
    128
    Here's the C# side, notice the giant delegate type declaration. This is not needed in JavityScript.

    Code (csharp):
    1.  
    2. public delegate void P2PClientFunction(String facilitatorIP
    3.         , int facilitatorPort
    4.         , String proxyIP
    5.         , int proxyPort
    6.         , String proxyPassword
    7.         , String connTesterIP
    8.         , int connTesterPort
    9.         , bool hostUseNAT
    10.         , String hostIP
    11.         , int hostPort
    12.         , String externalIP
    13.         , int externalPort
    14.         , String hostGUID
    15.         , String hostPassword
    16.         , int useProxy
    17.         , String joinerExternalIP);
    18.  
    19. public void SetP2PClientFunction(P2PClientFunction function)
    20. {
    21.     Hashtable context = new Hashtable();
    22.     context["function"] = function;
    23.     motigaAdapter.SendMessage("adapterSetP2PClientFunction", context);
    24. }
    25.  
    26.  
    Aside from not realizing the Func template was available to Unity, what else am I missing?

    I think you're missing my central point, it's the need to declare the delegate type for each type of lambda expression. You don't need to do this in JavityScript, and nowhere in my code do you have the need for delegate type declarations. In your case, the first snippet it's hidden by a template expansion, and in the second case you're declaring a generic version. I contend that, to my sensibilities, it's inelegant and adds more work outside of the context you're working in. I don't see that you refuted this assertion at all.

    Nitpicky, only correct in the sense that it's immutable data, which is usually the case when you are doing array initialization in code rather than data. This works just fine:

    Code (csharp):
    1.  
    2. var test = ["hello", "cheese", "I love America"];
    3. test += ["fun"];
    4. print(String.Join(", ", [s for (s in test)]));
    5.  
    Though I'd typically use a comprehension or iterator, here's your version transliterated:

    Code (csharp):
    1.  
    2. var test = new List.<String>(["hello", "cheese", "I love america"]);
    3. test.ForEach(function(x) {print(x);});
    4.  
    One thing JavityScript hasn't gotten from C# yet is the new container initializers, and that's a drag because there is an extra allocation above, but for most of my code I'm not declaring lists in code, they are in data so it hasn't impacted me.

    See, all programmers have some common ground :) I respect your opinions, I'm not trying to tell you you shouldn't be happy with what you know well, which is C#. Having myself worked with many different languages (thankfully not Brainfuck) there are some features I really find elegant, and I find that with the way lambda functions are supported in JavityScript.
     
  2. TheCasual

    TheCasual

    Joined:
    Sep 30, 2010
    Posts:
    1,286
    Hes not using UnityScript, hes using JavityScript :p
     
  3. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Don't you have to repeat all this crazy signature every time you write a new function body in UnityScript?

    I'd better do it this way:
    Code (csharp):
    1. class P2PClientArgs
    2. {
    3.     public string facilitatorIp;
    4.     public int facilitatorPort;
    5.     public string proxyIp;
    6.     public int proxyPort;
    7.     public string proxyPassword;
    8.     public string connTesterIp;
    9.     public int connTesterPort;
    10.     public bool hostUseNat;
    11.     public string hostIp;
    12.     public int hostPort;
    13.     public string externalIp;
    14.     public int externalPort;
    15.     public string hostGuid;
    16.     public string hostPassword;
    17.     public int useProxy;
    18.     public string joinerExternalIp;
    19. }
    20.  
    21. void Test()
    22. {
    23.     Action<P2PClientArgs> f = args => Debug.Log(args.facilitatorIp);
    24.     SetP2PClientFunction(f);
    25.  
    26.     SetP2PClientFunction(args => Debug.Log(args.hostIp));
    27.     SetP2PClientFunction(args => Debug.Log(args.connTesterIp));
    28. }
    29.  
    30. public void SetP2PClientFunction(Action<P2PClientArgs> clientFunction)
    31. {
    32.     var context = new Dictionary<string, Action<P2PClientArgs>>
    33.                     {
    34.                         {"function", clientFunction},
    35.                     };
    36.     motigaAdapter.SendMessage("adapterSetP2PClientFunction", context);
    37. }
    It would be nice also to get rid of "string typing" inside SetP2PClientFunction and change strings to enums.

    Code (csharp):
    1. var f = () => null;
    What is the return type?

    Code (csharp):
    1. int a = 0;
    2. var f = x => a += x;
    Does it return int or void?

    Code (csharp):
    1. var f = x => x == 0;
    Is it Predicate<int> or Expression<Predicate<int>> ?

    Code (csharp):
    1.         Expression<Predicate<int>> expression = x => x == 0;
    2.         Debug.Log(expression); // prints "x => (x = 0)"
    3.  
    4.         var f = expression.Compile();
    5.         Debug.Log(f.Invoke(10)); // prints "false"
    6.  
     
    Last edited: Feb 8, 2012
  4. squidbot

    squidbot

    Joined:
    Jan 4, 2011
    Posts:
    128
    The delegate declaration is not a function body. In JavityScript I don't need to declare a delegate with the same parameters I've already typed for my function declaration. In C# I do.

    You'd better not as that wouldn't be compatible with the libraries I'm working with :)

    Snipped the rest. You're confirming the limitations of the lambda expression format being different than the normal function declarations. In JavityScript I can declare the return types of my lambdas and thus don't have this problem, in my book that is more elegant.
     
    Last edited: Feb 8, 2012
  5. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    I had a post, the decided to ditch it... however this thread continues:

    I find it surprising that have multiple requests you simple will not show this working in US.

    Potentially a lot. You've got into the mindset that JS is better - but don't know enough about C# to determine what's going on.

    We've already established that C# Lambda's are much shorter than JS - which lends them to all sorts of uses.

    Now prove that this is better. Remembering US has a history of 'features' that end up being a combination of more verbose, slower, less featured etc. So far your demonstrated a more verbose and less expressive alternative!

    What I would like to know is how DOES US handle the signature problem found in C#? [Remembering of course, this could be in a Library exposed to US.]

    Code (csharp):
    1.  
    2. class Program
    3.     {
    4.         static void Main(string[] lol)
    5.         {
    6.             A a = () => 1;
    7.             B b = () => 2;
    8.             Function(a);
    9.             Function(b);
    10.  
    11.             Console.ReadLine();
    12.         }
    13.  
    14.         delegate int A();
    15.         delegate int B();
    16.  
    17.         static void Function(A a) { Console.WriteLine("A " + a()); }
    18.         static void Function(B b) { Console.WriteLine("B " + b()); }
    19.     }

    I agree, the following constructs are just 'nitpicks':

    List, SortedList, LinkedList, Dictionary, SortedDictionary, Stacks, Queues, Various Tree Structures, BSON Documents etc.

    If you're going to use an iterator - you're going to have to get it working with LINQ [Which has all sort of beautiful concepts such as expression trees, streamed data, deferred processing etc.]

    Finally a translated version - more verbose. Obviously not impediments in most real world situations - but certainly not 'better'.
     
    Last edited: Feb 9, 2012
  6. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    I'm far from saying that any language is worse or better, it just would be nice to see how well the languages suit in different situations.
     
  7. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    While each language has its merits, I do not have a deep understanding of what c# is capable of so I can make comparisons.
    After reading other people's experiences, along with my personal experience I have concluded to the following :

    1. UnityScript is well suited to code game logic. It is less verbose and gets the work done right, if used with care. The lack of references is partially filled by unity ( and others ) tutorials where you can learn some "patterns" of how to use it. The lack of foundations cannot be substituted by studying code only and the need of a reference and some more in-depth programming tutorials is evident. But it works.

    2. UnityScript has access to most .NET classes but not to all. I.e List, SortedList, LinkedList, Dictionary, SortedDictionary, Stacks, Queues are accessible. Multiple interfaces, elegant LINQ expressions ( as opposed to this approach ), Events are non - or partially accessible. To my understanding, such features are more useful to people creating advanced frameworks or components. I can be mistaken, your feedback on this is much appreciated.

    3. Use of C# is not synonymous to good code and use of UnityScript is not synonymous to bad code. Chances are though that people that code in C# already have a good foundation that permits them to do more. Problem is that the transition from developing code for business applications to developing code for games takes time and experience, for any developer. Please correct me if I am wrong but I think C# delegates, LINQ and other features can be considered too heavy for use in games, performance - wise. I have read some critics that even Events performance is bad ( people used this argument to explain why the Unity GUI is not performing so well - besides the multiple draw calls issue ). I do not claim that C# is bloated for games - I just say it takes time and experience to figure out what works best and some of the "advanced " features can cause performance troubles. To my knowledge, the "favorite" data type for most things in a simple game is the Array, due to its speed ( I do not claim that other data types do not have their merits for games, I just notice that Arrays seem to be the most heavily used ).

    I would appreciate if people more well - versed in programming could comment on the above, as my knowledge on these matters is limited.
    Thanks,
    -Ippokratis
     
    Last edited: Feb 9, 2012
  8. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Interfaces and abstract classes might be useful to describe a hierarchy or in-game items, like

    abstract class Carriable { ... }

    abstract class Tool : Carriable { ... }

    class Apple : Carriable { ... }
    class Axe : Tool { ... }
    class Hammer : Tool { ... }

    or

    class Apple : ICarryable, IEatable { ... }
    class Axe : ICarryable, IWeapon, ITool { ... }

    or you may prefer composition over inheritance, but at least you have a choice to use whatever suits your needs better.

    Delegates might be slower than direct or virtual function calls, but that's fine unless you call them a million times per second. However, information about delegates' speed is discrepant and I have to investigate it deeper. The same about events.

    LINQ expressions, being very expressive, can be slower than manual calculations or can be faster. It depends. Anyway, when a player clicks a button and something should happen once, in this case I prefer to use LINQ if it makes the code more readable.

    Don't use Array (in UnityScript) or ArrayList (in C#) - they are slow, because are not typed. Either use built-in arrays:
    var array = new int[1000];

    or generic collections:
    var list = new List<int>();
     
    Last edited: Feb 9, 2012
  9. Starsman Games

    Starsman Games

    Joined:
    Jan 30, 2011
    Posts:
    2,152
    I dont know the others since I only seek stuff by reference as you stated, but I currently use dictionaries in JavityScript. Here is a snippet from my analytics code:

    Code (csharp):
    1. var myDict = new Dictionary.<String, String>();
    2. myDict["Level"] = Application.loadedLevel.ToString();
    3. myDict["LevelName"]     = Application.loadedLevelName;
    4. myDict["Source"] = reason;
     
  10. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    While I do agree it can work [and if you're that type of person, best of luck!], I disagree it's less verbose. I would say it simplifies the simple things.

    Quick Question - has anyone got an example of US extension methods?

    My specialty is networking and I use Lambda's and Linq extensively [and so do some of the frameworks I've used]. Events not so much, though I think I've got a few cases in my code where it might greatly simplify things.

    To say that they are too 'heavy' often means the developer is ignorant of their proper application. If I can use them, and get tens, hundreds or thousands of players on a server - what exactly are they programming that is too intensive?

    Hell EVE runs on PYTHON!

    Generally good :)
     
  11. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    I think you should reread that quote:

    2. UnityScript has access to most .NET classes but not to all. I.e ...Dictionary... [is] accessible.

    The problem is the 'i.e' it should be e.g. as well as the general structure which is slightly misleading.


    Edit: I know this thread is well derailed, but just realized how funny the following is:

    The array is an excellent lightweight datatype. That said it's not magical.

    Many developers get into the mindset that arrays are fast and therefor they should use them. So instead of using the appropriate collection [e.g. List<T> is often better due to its dynamic sizing], they force themselves to use an array and spend an inordinate amount of time working around its limitations.

    The funny thing is that if performance was as critical as they claimed, often the array would be a hideous choice, and they should have used a trie/dictionary/sorted-list/structs/classes etc. all along!
     
    Last edited: Feb 9, 2012
  12. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Speaking of which : I recently made some extensive tests with List<T>, and this class is awfully slow for what it serves. It is slower than ArrayList, and of course much much slower than Dictionaries :) (because it's O(n), instead of O(1)).

    All to say that if anybody is interested in finding a faster version of List<T> (and ArrayList), I wrote an unsorted one based on Dictionary structure (warning : unsorted, so basically as fast as a built-in array but with List functions).

    Link to the class.

    Holy cow o_O

    I'm using this language to code automation scripts in Cinema 4D, and it's a real pain to maintain even a 30 lines long script !
    So I couldn't imagine a whole MMO framework .... :s
     
  13. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Be very careful when you say things like that - because it's false.

    List.Count is O(1).
    List[] is O(1).
    List.Add() is O(1) where List.Count<List.Capacity else it's O(n) where List.Count is N for the re-sizing.
    List.Exists(), List.Find() and List.FindAll() are all O(n)
    etc.

    It depends entirely on what you are doing - and as you've not said... there's little value to that particular statement. Give me your benchmarks and I'll see what the problem is :)

    :)
     
    Last edited: Feb 9, 2012
  14. Starsman Games

    Starsman Games

    Joined:
    Jan 30, 2011
    Posts:
    2,152
    Woops, missed that and yes, you are right, it was precisely due to the 'i.e'
     
  15. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Ha yes, absolutely, but we can all assume that using a List without exceeding its capacity, or any Exists()/IndexOf() like function is kind of very rare in video games :)
     
  16. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Not really.

    This is how I often use list:

    Code (csharp):
    1.  
    2. var list = new List<string>(100) //Not that I normally put in initial capacity - but you can.
    3. list.add("LOL");
    4. list.ForEach(print);
    5.  
    No capacity overflows, No looking up if items exist etc.

    Stop making completely baseless assumptions about how it is used, and instead provide your benchmarks.
     
    Last edited: Feb 9, 2012
  17. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    I think the real advantage of Dictionaries vs Lists is the speed of the Contains() method
     
  18. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    What the hell ?

    Anyhow, are you implying that only a minority of game devs do use the List<T> Contains(), Find(), or IndexOf() functions ? Really ?


    Yes absolutely, thanks :)
     
    Last edited: Feb 9, 2012
  19. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    Thanks for taking the time to provide so much feedback :)
    For me it is a great chance to exchange views and ideas and to clear up questions, your feedback is very appreciated !

    There are many discussions on data - driven vs object oriented approaches for games. One point learned from these discussions is that by using a "compositional" approach ( which is btw the "recommended" Unity way of building code ) vs a inheritance approach you get better memory organization ( continuous vs fragmented blocks of memory ) and caching. We cannot play with the source so there is no way to apply caching optimizations but we can achieve better memory organization using the "compositional" approach. I think.

    Depends on the platform and the desired complexity. For mobile, where resources are limited, some developers might consider these as a pricy luxury.

    Would it be possible to direct me to some references that demonstrate the later or explain me a little more on this ? I really wish to find out more on that.
    My bad, I did not specified that I was talking about the built-in arrays. I totally agree with you ( and thankfully I am aware of this ).

    If you read again, you will notice that I said
    Thanks for sharing anyway.
     
  20. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    The real difference between HashSet/Dictionary and List is that the first is a set, and the last is a list. Other differences, advantages and disadvantages in certain circumstances follow from this fact.
     
    Last edited: Feb 9, 2012
  21. squidbot

    squidbot

    Joined:
    Jan 4, 2011
    Posts:
    128
    I assumed because I already had demonstrated it. Here is the full comparison between how the two language would work, snipped and refactored for brevity.

    C#
    Code (csharp):
    1.  
    2. public delegate void P2PClientFunction(String facilitatorIP
    3.         , int facilitatorPort
    4.         , String proxyIP
    5.         , etc...);
    6.  
    7. private void SomeCallback(String facilitatorIP
    8.         , int facilitatorPort
    9.         , String proxyIP
    10.         , etc...)
    11. {
    12. }
    13.  
    14. public void SetP2PClientFunction()
    15. {
    16.     Hashtable context = new Hashtable();
    17.     context["function"] = this.SomeCallback;
    18.     motigaAdapter.SendMessage("adapterSetP2PClientFunction", context);
    19. }
    20.  
    JavityScript
    Code (csharp):
    1.  
    2. private function SomeCallback(facilitatorIP : String
    3.         , facilitatorPort : int
    4.         , proxyIP : String
    5.         , etc...)
    6. {
    7. }
    8.  
    9. public function SetP2PClientFunction()
    10. {
    11.     var context : Hashtable = new Hashtable();
    12.     context["function"] = this.SomeCallback;
    13.     motigaAdapter.SendMessage("adapterSetP2PClientFunction", context);
    14. }
    15.  
    Again, please point out specific shortcomings in my understanding of C#. There's a good chance I know more about it than you suspect. My mindset is use the most elegant tools for the job, and in this case, I find it's JS.

    As long as you conflate "short" with "elegant" you're not arguing the same point. And, as shown by the inability of C# to do local type inference on lambdas, I believe it is more limited.

    It's a rehash of the concept I show code for above, but here you go, in JS:

    Code (csharp):
    1.  
    2. // refactored your code to make sense when function signatures are the same
    3. class Program
    4. {
    5.     static function Foo()
    6.     {
    7.         var a = function() : int {return 1;};
    8.         var b = function() : int {return 2;};
    9.         Func(a);
    10.         Func(b);
    11.     }
    12.  
    13.     static function Func(bar : Function) { Debug.Log(bar()); }
    14. }
    15.  
    16. // translate your code to deal with two different signatures
    17. class Program2
    18. {
    19.     static function Foo()
    20.     {
    21.         // No need for types here, inference does the job
    22.         var a = function() : int {return 1;};
    23.         var b = function() : String {return "hi";};
    24.         Func2(a);
    25.         Func2(b);
    26.     }  
    27.  
    28.     // notice that we've now differentiated the type differentiation where it's used
    29.     // rather than elsewhere in the code. I've not had to set up a delegate and remember where it's
    30.     // declared
    31.     static function Func2(bar : function() : int) { Debug.Log(bar());}
    32.     static function Func2(bar : function() : String) {Debug.Log(bar());}
    33. }
    34.  
    I don't really follow any of this, it seems to stray from your original point? And again, short is not the same as elegant. And my original argument had nothing to do with verbosity, that was your argument. It had to do with the inelegance of having to declare delegate types when you made lambda expressions rather than that work being done as a language feature.

    Anyway, I didn't really post my original comment to get in to an argument or even argue JavityScript was better in all ways than C#, and honestly, I shouldn't have taken the bait. I was simply pointing out one feature I prefer in JS over C#.

    The fact is, the next library I'm going to write will be in C# because it's become the lingua franca for most people in Unity, and when I need a third party tools library, it's going to be in C# typically, not JS. This made it impossible for me to make my JS code work as a plugin when it needed to be consumed by C# code due to the limited compilation stages of Unity.
     
  22. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Nope, what I am clearly stating is that making announcements of 'greater performance' without stating your use-case is wrong.

    If you're task requires a fast lookup on a non-trivial amount of data, you probably shouldn't use a List. To go from that to saying it is slow is false and spreads misinformation.

    I just built a benchmark that proves your system is 280% slower than list :p
     
    Last edited: Feb 9, 2012
  23. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    In fact I based my claim on several user topics found on stackoverflow.net ;-)
    (which is where I got the base hashSet hacked class too, so ...)

    Lol if I don't want to go crazy again with benchmarks, I think I'll leave it as it is now :p

    For precision : I used a Contains() bombing on a 10 long list to benchmark the stuff, because I was looking for Contains() performance.
     
  24. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    My point exactly. Now you're providing valid info :)
     
  25. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    Sorry ;-)
    (I innocently thought Contains() was too vital for game logic coding not to be taken into account)
     
  26. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Actually HashSet and Dictionaries have some differences too.
     
  27. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi NPFS3000,
    Thanks for taking the time to provide feedback, my answers to your points of view are taking too much space, hence the separate post. This thread moves fast.

    E.g when code is interacting with structs, which are all over Unity API, UnityScript is less verbose.

    Sorry, could you please rephrase? I do not really understand the question.

    I wish to clear that by "heavy" I mean "perhaps you could achieve similar results with less elegant code and less performance cost". I already admitted my lack of knowledge on how to effectively use these features, I believe that the balance between coding right - fast - efficient is something people learn progressively and I have more to learn. It seems to me that it is "right" to code conservatively ( resources - wise ) when writing real-time code.

    Thanks, I was not aware of these semantics ( my Engrish gets better with these discussions : )


    Actually, my quote is
    Are you suggesting that I am derailing this thread ? Where is my sword ?

    Totally agree with you ( I tried once to joke in #unity3d saying that "Lists are evil". Next ten posts was along the lines " Burn the heretic !" :) )

    I agree that List is more flexible for certain tasks and this flexibility worth its cost in certain situations.

    Obviously it depends on the problem. Another factor besides performance cost and ignorance is the time it takes to create -debug -maintain code. Maybe you know that an octree is the best data type for a given problem but if you have no idea how to create - effectively use - integrate - maintain - debug an octree, its cost in development time becomes too high. Costs add up and to finish a product you choose what to cut - this is another valid reason.

    On the funny side of things, why are you so passionate about C# ?
    Is it a
    REAL MEN CODE IN C# thing ?

    Relax mate ! It is summer in Australia ( and we have a damned cold in Athens, I am so envy ! ), have a Mohito :)

     
    Last edited: Feb 9, 2012
  28. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    So you are getting a function, casting it to an object, sending it off to someone else and praying they know what to do with it?

    How do you maintain performance and strong typing? Or do you just give 'em up?

    I'd argue that short, less cluttered is always more elegant than a longer cluttered version given the same info is expressed. However just for laughs I present the following:

    Code (csharp):
    1.  
    2. var mult = function(x : int) {return x * x;};
    3. var addStr = function(s : String) {return s + s;};
    4.  
    5. var mult = function((int x) => { return x * x; });
    6. var addStr = function((string s) => { return s + s; });
    7.            
    8. var mult = function((int x) => x * x);
    9. var addStr = function((string s) => s + s);
    10.  
    I note the following:

    If any library presents overloading based on the delegate your stuffed. Not that I've seen anything, but it's something I'll be looking out for.

    You once again forgot about the Func<> when you said:

    Whether you like how it works or not - it does present a simple way to 'forget' about delegates.



    If you're going to write comparison code - make sure the same code has similar functionality. Arrays and iterators do not meet that requirement.

    See my earlier code :p
     
  29. Starsman Games

    Starsman Games

    Joined:
    Jan 30, 2011
    Posts:
    2,152
    What are you, a baby?!


    Real men code in ASSEMBLY!!!!
     
    Last edited: Feb 9, 2012
  30. n0mad

    n0mad

    Joined:
    Jan 27, 2009
    Posts:
    3,732
    lol ! Yeah but

    Real men DELEGATE the need to code !!!!
     
  31. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    uScript doesn't delegate, it infers!
     
  32. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    On a second thought, maybe I am derailing this thread...
     
  33. Starsman Games

    Starsman Games

    Joined:
    Jan 30, 2011
    Posts:
    2,152
    Real men manually assign the memory address as a pointer to for callback variables to invoke!!!!

    Manually!!! No cheating letting the compiler assing the address!!! BECAUSE YOU DO IT IN ASSEMBLY!!!!
     
  34. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    And if you only ever interact with structs, then I'd agree with you. Given that you don't, you have to look at the language as a whole.

    Not really directed at you, but if you insist:

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Linq;
    4.  
    5. public class StructTest : MonoBehaviour
    6. {
    7.     // Use this for initialization
    8.     void Start()
    9.     {
    10.         //This works
    11.         var v3 = new Vector3(1, 1, 1);
    12.         v3.y += 1;
    13.         print(v3);
    14.         //So does this
    15.         var V3Array = new Vector3[1];
    16.         V3Array[0] = new Vector3(1, 1, 1);
    17.         V3Array[0].y += 1;
    18.  
    19.         print(V3Array[0]);
    20.  
    21.  
    22.         //This doesn't!
    23.         //transform.position.y += 1;
    24.  
    25.         //Solution?
    26.  
    27.         //Extention!
    28.         transform.position += 1.Y();
    29.  
    30.         //Now I'll admit this might not be a best use, if you want a good use take a look at LINQ
    31.         //For Example
    32.         print(V3Array.Contains(new Vector3(1, 1, 1)));
    33.  
    34.         //Tells me if V3Array contains a certain Vector... even though this is not a function of the array Class!
    35.     }
    36. }
    37.  
    38. public static class Extentions
    39. {
    40.     public static Vector3 Y(this float y)
    41.     {
    42.         return new Vector3(0, y, 0);
    43.     }
    44.     public static Vector3 Y(this int y)
    45.     {
    46.         return new Vector3(0, y, 0);
    47.     }
    48. }
    Nope. While one should not be wasteful, the vast majority of code is not performance intensive. However, every $ spent in a game [ESPECIALLY AN INDIE GAME] is a huge challenge to make back.

    Make your code clean and easy to understand. Make your code fast to write. Make sure you reuse code, and have smart algorithms.

    Prematurely worrying about efficiency is wasting the most valuable resource - Time.

    Didn't even notice - my congrats!

    I know, I just used it as an opportunity to provide an anecdote.

    Note, I'll accept the responsibility :)

    That's a very nice summary.

    Exactly. But I think you'll find that gap where an Oct tree is too Dev expensive, but an List [ or other generic] too computationally expensive very very slim. I should remind the reader this argument starts with the assumption that the array wasn't the best fit for the task - because arrays are great to use.



    I learnt half a dozen languages, including US before choosing to focus on C#. Then I've spent the last year or so building expertise [books, stack overflow, blogs] in it. It's quite amazing.

    That's not to say it's good for everything - I could spend an hour or so expunging on Erlangs awesomeness - but you're not going to get simple comments past me like 'US is less verbose' without me providing some form of clarification or argument.

    So this is half defense of C#, half wanting to learn about new languages.
     
  35. Starsman Games

    Starsman Games

    Joined:
    Jan 30, 2011
    Posts:
    2,152


    You cant derail a thread that is already derailed.

    (It's like the undead... but with forum threads)​
     
    Last edited: Feb 9, 2012
  36. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    Yep

    Use of LINQ sometimes can make your code do less work because LINQ is lazy. It won't do any work unless it is really necessary to be done. You can google for "linq lazy" keywords.

    Code (csharp):
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4.  
    5. internal class Item
    6. {
    7.     public int Data { get; set; }
    8.  
    9.     public Item(int data)
    10.     {
    11.         Console.WriteLine("some expensive calculations... ({0})", data);
    12.         Data = data;
    13.     }
    14. }
    15.  
    16. internal class Program
    17. {
    18.     private static void Main(string[] args)
    19.     {
    20.         var collection1 = Enumerable.Range(1, 20).Select(n => new Item(n));
    21.         ProcessCollection(collection1, false);
    22.  
    23. // Output:
    24. // some expensive calculations... (1)
    25. // some expensive calculations... (2)
    26. // some expensive calculations... (3)
    27. // some expensive calculations... (4)
    28. // some expensive calculations... (5)
    29. // Collection contains '5': True
    30.  
    31.         Console.WriteLine("---------------------------------------");
    32.  
    33.         var collection2 = new List<Item>(20);
    34.         for (int i = 1; i <= 20; i++)
    35.         {
    36.             collection2.Add(new Item(i));
    37.         }
    38.         ProcessCollection(collection2, false);
    39.  
    40. // Output:
    41. // some expensive calculations... (1)
    42. // some expensive calculations... (2)
    43. // some expensive calculations... (3)
    44. // some expensive calculations... (4)
    45. // some expensive calculations... (5)
    46. // some expensive calculations... (6)
    47. // some expensive calculations... (7)
    48. // some expensive calculations... (8)
    49. // some expensive calculations... (9)
    50. // some expensive calculations... (10)
    51. // some expensive calculations... (11)
    52. // some expensive calculations... (12)
    53. // some expensive calculations... (13)
    54. // some expensive calculations... (14)
    55. // some expensive calculations... (15)
    56. // some expensive calculations... (16)
    57. // some expensive calculations... (17)
    58. // some expensive calculations... (18)
    59. // some expensive calculations... (19)
    60. // some expensive calculations... (20)
    61. // Collection contains '5': True
    62.  
    63.         Console.ReadLine();
    64.     }
    65.  
    66.     private static void ProcessCollection(IEnumerable<Item> collection, bool someCondition)
    67.     {
    68.         if (someCondition)
    69.         {
    70.             // Here we use all the elements
    71.             foreach (var item in collection)
    72.             {
    73.                 // Do something useful
    74.             }
    75.             Console.WriteLine("All items processed");
    76.         }
    77.         else
    78.         {
    79.             // Sometimes it's not necessary to process all the elements to get things done
    80.             var containsFive = collection.Any(item => item.Data == 5);
    81.             Console.WriteLine("Collection contains '5': {0}", containsFive);
    82.         }
    83.     }
    84. }
    85.  
    The example is a bit artificial but it's just an example.

    I'm also a little bored with -20°C outside for two weeks already. I wish it finally change in whatever direction.
    $athens.PNG
    hahaha
     
    Last edited: Feb 9, 2012
  37. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Here's a slightly better example:

    Code (csharp):
    1.  
    2. class MyDictionary
    3. {
    4.     static string GetDefintion(string word)
    5.     {
    6.         return (from line in new StreamReader(new FileStream("Oxford.csv", FileMode.Open)).Lines()
    7.                 where line.Split(',')[0] == word
    8.                 select line.Split(',')[1]).First();
    9.     }
    10. }
    11.  
    12. public static class TextReaderExtensions
    13. {
    14.     public static IEnumerable<string> Lines(this TextReader reader)
    15.     {
    16.         string line;
    17.         while ((line = reader.ReadLine()) != null) yield return line;
    18.     }
    19. }
    Hypothetical scenario: Kindle.

    You have little memory, slow CPU and Storage.
    You need to read in a comma spaced file to get the dictionary definition of a word.
    Dictionary access are sporadic.

    With the above lines of code the function only reads in as much data as necessary, can free memory after it's been rejected, is easy to maintain etc.

    If you ever decide to build an index and jump to the right entry - the above code can be modified to read in the index :p
     
    Last edited: Feb 9, 2012
  38. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    alwxzzzzz :
    :D
    If I cannot drink a Mohito in a beach bar next to the sea because it is cold then we have damned cold :p
    Lately, my friends at Rhodos told me that there is a healthy flow of Russian tourists, if you go to Rhodos, try the "Mohito Bar" :)

    When I declare
    I actually create a new struct, without using the "new" keyword. In my example, this is a "hidden" cost. Are you aware if there is such a "hidden" cost for Linq ? There is this article that explains why Linq is usually nicer but slower.
    Would you like to post some example that demonstrates that a LINQ implemented is faster ( it is without doubt cleaner ) ?
     
    Last edited: Feb 9, 2012
  39. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Dude, there are hidden costs - if you don't like that go and design your own hardware [even assembly has hidden costs].

    The key is to evaluate all the costs, and give the best solution. Off the top of my weary mind I would prioritization most things according to:

    1. Readability.
    2. Developer Time.
    3. Algorithm design.
    4. Micro-Opts.

    What people do when they talk about LINQ being expensive [or lambdas, or lists, or events, or a myriad of other C# abilities] is they often do the following:

    1. Micro-Opts.
    2. Algorithm design.
    3. Developer Time.
    4. Readability.

    So the code ends up being costing a lot, being a nightmare to maintain and more often than not being slower than the correctly structured system.

    For example with LINQ it uses a lot of differed processing - so while it might not be great on the micro-opt front it's immediately better than the alternative code of similar cost because of better algorithm. It uses far less time to use existing solutions - and leads to far less bugs. And of course, LINQ, written well, is often close to human language, making it very good for readability.

    As you asked for an example - write the classic version to my earlier example. Remembering to conveniently forget to stream the data, and then load in a dataset that's twice the size of your memory.
     
    Last edited: Feb 9, 2012
  40. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    NPSF3000 :
    Ok, you type fast !

    It is less verbose to create a simple class.
    Code (csharp):
    1.  
    2. //Stupid little examples UnityScript
    3. //Class creation
    4. //filename : example.js
    5. var pos : Vector3;
    6.  
    7.  
    Code (csharp):
    1.  
    2. //Stupid little examples C#
    3. //Class creation
    4. //filename : example.cs
    5. using UnityEngine;
    6. using System.Collections;
    7.  
    8. public class example : MonoBehaviour
    9. {
    10.     public Vector3 p;
    11. }
    12.  
    13.  
    It is less verbose to access components
    Code (csharp):
    1.  
    2.  //Stupid little examples UnityScript
    3. //Accessing components
    4. transform.localPosition = Vector3(0, 0, 0);
    5. print(transform.localPosition.y);
    6.  
    Code (csharp):
    1.  
    2.  //Stupid little examples C#
    3. //Accessing components
    4. using UnityEngine;
    5. using System.Collections;
    6.  
    7. public class example : MonoBehaviour {
    8.     void Awake() {
    9.         transform.localPosition = new Vector3(0, 0, 0);
    10.         print(transform.localPosition.y);
    11.     }
    12. }
    13.  
    It is less verbose to deal with Types
    Code (csharp):
    1.  
    2. //Stupid little examples UnityScript
    3. //deal with Types
    4. function Awake()
    5. {
    6.     var GO = new GameObject("Player", MeshRenderer, MeshFilter )
    7. }
    8.  
    Code (csharp):
    1.  
    2.  //Stupid little examplesC#
    3.  //deal with Types
    4. using UnityEngine;
    5. using System.Collections;
    6.  
    7. public class example : MonoBehaviour
    8. {
    9.      function Awake()
    10.      {
    11.         public GameObject GO = new GameObject("Player",typeof(MeshRenderer), typeof(MeshFilter) );
    12.      }
    13. }
    14.  
    I *think that it is possible to access the Extentions class via javascript, I am not aware of how to code it in UnityScript. It seems to me that "extensions" in the context you used it is the ability of creating new classes that extend the functionality of existing ones. Some things work, other not, the implementation is not as complete as in C#, hence my argument on viewing C# more suited for components creation.

    For me, a drawback of UnityScript is the lack of ref and out keywords, not for creating classes but for using them. Bad. You can use another "intermediate" c# class but it is not nice. Or fast.

    Time is an asset - no doubts. Fast made, readable, reusable code, fast, maintainable code, add yours. Perhaps coding is about balancing between those desirable outcomes. I still believe that real time applications should have fast code as a priority but I respect your POV. Perhaps I should add that a priority doesn't mean the only priority, to make my POV clearer.

    That's it, say time and place !

    Damn, I am slow.

    [EDIT] I cannot keep up with this, you write too fast ! Swords down :p
     
    Last edited: Feb 9, 2012
  41. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Wow I never realised how good I'm getting at touch typing - I still look down a lot though :(

    </Considers investing time in proper mastery>.

    That's a classic example.

    It's less verbose to create a class but it hides the important fact that not every class has to be a monobehaviour.

    The time it takes to create a proper C# class is no different (Unity creates it based on a template for you) - the cost of a limited mindset, at least in my experience - huge.

    Lastly, your brain recognizes code patterns and fluff - it's not like you actually read every line every time you see a class.

    So yeah, this fits my opinion [though I don't think I've mentioned it yet this thread] UnityScript is for Scripting, C# is for programming.

    Though while we are at it, why include System.Collections?

    Nope - look at your code it's near identical. Furthermore the including of the using and class servers no purpose as you've already covered it. Don't make me accuse you of double counting :p

    Code (csharp):
    1.  
    2.         transform.localPosition = Vector3.zero; //fixed
    3.         print(transform.localPosition.y);
    4.  
    First time I've seen that function used.

    Code (csharp):
    1.  
    2. var GO = new GameObject("Player",typeof(MeshRenderer), typeof(MeshFilter) );  //Fixed
    3.  

    That's pretty much my knowledge of it. Though anyone tells me they need to do the 'hardcode' stuff in C# and the light stuff in US and i'll go on a rant about how US is nothing more than a turning-incomplete parasitical monster :p

    I need to point out that all you've pointed out are trivialities 'making simple things simpler'. Powerful things like events, extensions, linq, structs, lambda, properties, ref/out etc. are harder to do/less clear in US IIRC.

    I tried to go back to US for a client. Problem was is everything I'm used to doing was so poorly documented it was too costly to be worth the while.

    I'll just repeat what I said earlier. I do network programming. It's very complicated [hence my love for C#]. However I sit down and analyse the performance of every single action - down to the BIT on occasion. I've yet to run into a performance bottle neck that required micro-optimization but constantly struggle to manage the interactions between my systems.

    There are situations where performance is important - but wait until you can actually PROVE that that's so before wasting time on optimizing.

    Dude, this is my sword :p

    Man that was a long time ago.
     
  42. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    If you worry about Delegate/Event speeds, NEVER use any built-in MonoBehaviour functions. Avoid all Awake, Update, On____, because these are absolutely massively slower than delegate invocation.

    In fact, proper use of these structures can be improving speed, for A) They have built in advantages like Linq/IEnumerators ability to only initialize(in some instances) the elements it is going to be using rather than all possible elements, while maintaining a small code base. This helps garbage collections/allocations, and can provide you with less memory use.
    And B)for Delegates/Events/etc.. you need to take into account you are not having to call X.Get() before invoking your functions, or call find() or grab proper references at the time you need to invoke these functions.

    In some situations Delegate calls in C# are as fast (and possibly even faster in edge cases) than virtual function calls: http://stackoverflow.com/questions/2082735/performance-of-calling-delegates-vs-methods

    And Regardless you are going to have thousands to tens of thousands (or more) of other bottlenecks taking up more relative time that could be optimized easier and faster, long before cutting into the readability, debugability and overall ease of use these structures provide.

    In the proper situations these save you programmer time ($) and processor time. The amount of time spent to create equivalent systems and structures costs you time, and time is money.

    If you use C#, don't ignore these features under the assumption that they are somehow slower than more basic systems, and don't dismiss programmer time as a valuable asset when programming.

    Overall calling these things slow is wasteful and harmful to actually creating something. Do you use ++i instead of i++ in your loops, so that they can run faster? These are never problem areas with the current computing power (even on handhelds), and trying to solve these problems means less time spent actually finding the real bottlenecks, cause no-one writes even close to perfectly optimal code.

    The same things apply to stuff like Ref/Out(potentially less work done to invoke the function stack allocation wise), Structs(less Garbage Collections, Heap Allocations), Properties(Compiler has some micro-optimizations over functions in some edge cases). These are built to be used and be advantageous over their existing systems. They are not slow, they are not ineffecient(any more than anything else). But their still all Micro-Optimizations and their real benefits are programmer ease of use.
     
    Last edited: Feb 9, 2012
  43. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi NPSF3000,

    I am trying to decide, should I create now a RTS - FPS - MMORG to prove you how wrong you are ( all of you ! ) or should I bite the bullet and start learning a thing or two about C# ? :p
    Jokes aside,
    Just out of curiosity, in this hypothetical scenario, could you integrate somehow a buffer in your code so you do not have to load the entire "Oxford.csv" in memory ? Or I get it wrong and this is exactly what the StreamReader does ? ( I am not playing smart here, since I played a while back with some big text files, I have this question ).

    Perhaps I have not expressed my POV correct, since you had to specify this. I totally agree with you on this one, since it is not clear from my previous post, I clear it here.

    Just because it is in the examples unity provided, thanks for pointing out that it is not needed.

    My sword AGAIN !

    It is a (kinda) recent GameObject constructor. Had to deal with lots of in-Editor gameObject generation and found it handy.

    I am getting bored of agreeing with you, let's fight !

    Overall, I am not arguing that less verbose is the A-Z in programming or that this specific quality justifies to use UnityScript for creating Nuclear Plants Operating Systems. You suggested that UnityScript isn't less verbose, I provided some "Stupid examples" that show some cases in which it takes less characters to achieve same results in UnityScript.

    I do want my code to run fast - not at any cost though. I am not qualified to create light-speed code in any language and if someone claims that creates high performance applications using a scripting language ( as far as I get it in the Unity context C#, UnityScript and Boo are scripting languages ) it sounds like a joke to me.
    I just try to make "less slow code", as I understand it. The c++ core does the job, I script the game logic and I try not to script in a way that slows things down even more. Again, not at any cost, we are on the same boat on this ( I hope you know how to swim :p ).

    Thanks for taking the trouble to explain all those c# advanced features, it is really appreciated. I am not saying "Do not use it, 'cause it is slow", I am just pointing out that they have a cost that one should consider as another factor aside the flexibility they provide.

    Ntero :
    Thanks for getting into trouble to provide all these examples, it is much appreciated. I agree with you, all your points are valid, thanks for sharing your views.

    I really enjoy such discussions, I certainly learned many new things, thanks a lot for the feedback,
    -Ippokratis
     
    Last edited: Feb 10, 2012
  44. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    What I'm preaching is well established! Eve uses python, Pikkoserver uses Erlang, Photon uses Lambdas, Unity uses C#. All slower than assemble :p. That said, C# allows more micro-opts than US :p

    As long as you don't call something stupid like sr.ReadToEnd() this is exactly what a StreamReader should do. How do I know this? Well think of it this way: What happens if the stream is a TCP socket, streaming audio etc. In these situations it ranges from impractical to impossible to contain all data in memory.

    Ahh nice. I've generally left that aspect of U3D alone.

    And as we've covered and agreed on, that's just a small aspect of the entire picture. BF can do somethings cleaner, clearer, more efficiently and less verbosely than any other language I know of. Still not going to use it as anything more than a mental exercise.

    Don't worry, I'm a Certified Diver, First Aider and Bronze Medallion [Life Saver].

    Exactly - what you need to do is learn what those costs are.

    Get VS C# Express. Learn to make console applications.

    Benchmark and test.

    Get C# in depth and use google + stack overflow to learn more about the features available and how they are used.

    On occasion, post your ramblings to paste-bin http://pastebin.com/u/NPSF3000
     
    Last edited: Feb 10, 2012
  45. snoopbaron

    snoopbaron

    Joined:
    Mar 21, 2009
    Posts:
    88
    I agree that C# has many advantages over UnityScript, but lets not forget that UniytScript does have one important advantage that C# will never have: Rodrigo Barreto de Oliveira :D.

    Rodrigo works for Unity and is also the creator of UnityScript's mother language Boo. UnityScript already saw important improvements in 3.x which included several missing features from C# while still keeping UnityScript's unique advantages. If you look at Boo you will also see that it already supports some of the C# features that are missing in UnityScript. For example, ref parameter support and creating (not just consuming) generics.

    Boo also has one extremely powerful feature that is not availble in C# or UnityScript, syntactic macros (not to be confused with C/C++ style preprocessor macros). Adding syntactic macros to UnityScript would allow you to write UnityScript code that runs at compile time (no runtime costs) that makes changes to your code before it runs. While I recall reading aboout Anders Hejlsberg considering adding syntactic macros to C# years ago it may never get them while Boo already has them and the potential for UnityScript to see them in the future seems much greater.

    That isn't to say that C# doesn't have its own special advantages like its mainstream status and support from Microsoft. But I believe with Rodrigo working at Unity, UnityScript and Boo have a bright future.

    Today pragmatically speaking I would start most new Unity projects in C#, but that could change in the future.
     
  46. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    This is an excellent point, and something people usually overlook in advanced technical discussions about Unity: You can use Boo to extend the compiler toolchain. Check out Rodrigo's talk from Unite 2010: http://unity3d.com/support/resources/unite-presentations/metaprogramming-and-plugins
     
  47. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Until he decides to have an epiphany and release the language specs, I'll still be a skeptic. FWIW all those features could all ready be implemented - we are just waiting for monkey to hit the right keys and take notice :p

    Very nice. I could certainly use some of those features...
     
    Last edited: Feb 11, 2012
  48. squidbot

    squidbot

    Joined:
    Jan 4, 2011
    Posts:
    128
    Boo and UnityScript are both open source, so you can see for yourself if they are implemented: https://github.com/bamboo
    I agree that a formal language spec would be nice rather than interpreting source code, but it is nice to have the source when you have questions.
     
  49. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    As far as I know you can manipulate the entire compilation process with Boo (ie, Boo scripts could manipulate compilation of your C# stuff)...
     
  50. kingcharizard

    kingcharizard

    Joined:
    Jun 30, 2011
    Posts:
    1,137
    I don't see a big deal, As a current Javascript(Web) programmer its not all that different than Web Js Yeah granted there are differences and it probably should be named Unityscript, but its not, atleast not at the moment. So no need to make it a big deal...

    Oh and a side note I program in C# but if i cant figure out how to do something in C# i try it in UnityScript and since i have a background in Javascript(Web) I usually figure it out and port it to C# so knowing Js is not a real set back not atleast in my mind...
     
    Last edited: Feb 13, 2012