proj-oot-ootNotes25

CaveTech? 15 hours ago [-]

PHP is stateless. You don't get to keep connections across requests.

reply

brianwawok 13 hours ago [-]

This is one of the reasons where PHP makes stuff so complicated.

...

---

naasking 4 hours ago [-]

No kidding. All kinds of robust operating system design went into seL4. It's simply crazy not to make use of it.

I can see potential problems already from looking at the Magenta kernel docs. For instance, they say that all syscalls are non-blocking except for explicit wait and sleep calls, which means the kernel is very likely vulnerable to various DoS? attacks, which aren't a problem for L4 kernels.

reply

---

" 2. Emacs relies heavily on global state. A global variable is a first-class citizen. When a package declares a global variable, it's a contract between the package author and the user that "You may configure the behavior of this package by binding this variable to a new value, then invoking one of my functions." Emacs lisp has language constructs which makes this easier: `(let* ((foo-state 42)) (foo-bar))` will update the global variable `foo-state` to 42, call the global function `foo-bar`, and ensures that `foo-state` is returned to its previous value even if an error occurs and an exception is propagated. In other words, global variables are the interface to a module, just like a module's functions, and global variables are almost never left in an unexpected or invalid state due to errors. "

---

great article on coding style: http://etodd.io/2017/03/29/thirteen-years-of-bad-game-code/

---

random guy's language ideas seem good:

http://computer-programming-forum.com/23-functional/bb62a50190b9928e.htm

---

https://www.slideshare.net/MattHarrison4/learn-90 https://github.com/mattharrison/Tiny-Python-3.6-Notebook

... . If you happen to learn everything about protocols, the interpreter gotchas, there is the standard library which is also huge, and if you got everything in it, there is the ecosystem, which is so large nobody can know about every package. And I did not talked about the whole new world of Python3, asyncio and the whole old world of Twisted.

reply

...(List) comprehensions are super cool, as are generators, decorators, etc, but there just wasn't enough time to cover that.

...

https://www.slideshare.net/MattHarrison4/learn-90 " ... Three Python'isms to Remember ● dir ● help ● colon/indent shuffle 10. Why Python? Python is a powerful, multi-paradigm, interpreted language popular with start-ups and large Co’s 11. Python 2 or 3? For beginners there is no real difference between Python 2 & 3. The basics are the same (except for print) 12. Hello World 13. hello world print "hello world" 14. from interpreter $ python >>> print "hello world" hello world 15. REPL Read, Eval, Print, Loop 16. REPL $ python >>> 2 + 2 4 >>> # # # read, eval print repeat (loop) 17. REPL (2) Many developers keep a REPL handy during programming 18. From script Make file hello.py with print "hello world" Run with: python hello.py 19. (unix) script Make file hello with #!/usr/bin/env python print "hello world" Run with: chmod +x hello ./hello 20. Python 3 hello world print is no longer a statement, but a function print("hello world") 21. Objects 22. Objects Everything in Python is an object that has: ● an identity (id) ● a value (mutable or immutable) 23. id >>> a = 4 >>> id(a) 6406896 24. Value ● ● Mutable:When you alter the item, the id is still the same. Dictionary, List Immutable:String, Integer, Tuple 25. Mutable >>> b = [] >>> id(b) 140675605442000 >>> b.append(3) >>> b [3] >>> id(b) 140675605442000 # SAME! 26. Immutable >>> a = 4 >>> id(a) 6406896 >>> a = a + 1 >>> id(a) 6406872 # DIFFERENT! 27. Variables a b c a = = = = 4 # Integer 5.6 # Float "hello" # String "4" # rebound to String 28. Naming ● lowercase ● underscore_between_words ● don't start with numbers See PEP 8 29. PEP Python Enhancement Proposal (similar to JSR in Java) 30. Math 31. Math +, -, *, /, (power), % (modulo) 32. Careful with integer division >>> 3/4 0 >>> 3/4. 0.75 (In Python 3 is integer division operator) 33. What happens when you raise 10 to the 100th? 34. Long >>> 10100 10000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000L 35. Long (2) >>> import sys >>> sys.maxint 9223372036854775807 >>> sys.maxint + 1 9223372036854775808L 36. Strings 37. Strings name = 'matt' with_quote = "I ain't gonna" longer = """This string has multiple lines in it""" 38. How do I print? He said, “I’m sorry” 39. String escaping Escape with >>> print 'He said, "I'm sorry"' He said, "I'm sorry" >>> print He said, "I'm sorry" He said, "I'm sorry" >>> print """He said, "I'm sorry"""" He said, "I'm sorry" 40. String escaping (2) Escape Sequence Output Backslash ' Single quote " Double quote b ASCII Backspace n Newline t Tab u12af Unicode 16 bit U12af89bc Unicode 32 bit o84 Octal character xFF Hex character 41. String formatting c-like >>> "%s %s" %('hello', 'world') 'hello world' PEP 3101 style >>> "{0} {1}".format('hello', 'world') 'hello world' 42. Methods & dir 43. dir Lists attributes and methods: >>> dir("a string") ['__add__', '__class__', ... 'startswith', 'swapcase', 'title', 'translate', 'upper', 'strip', 'zfill'] 44. Whats with all the '__blah__'? 45. dunder methods dunder (double under) or "special/magic" methods determine what will happen when + (__add__) or / (__div__) is called. 46. help >>> help("a string".startswith) Help on built-in function startswith: startswith(...) S.startswith(prefix[, start[, end]]) -> bool Return True if S starts with the specified prefix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. prefix can also be a tuple of strings to try. 47. String methods ● s.endswith(sub) Returns True if endswith sub ● s.find(sub) Returns index of sub or -1 ● s.format(*args) Places args in string 48. String methods (2) ● s.index(sub) Returns index of sub or exception ● s.join(list) Returns list items separated by string ● s.strip() Removes whitespace from start/end 49. Comments 50. comments Comments follow a # 51. comments No multi-line comments 52. More Types 53. None Pythonic way of saying NULL. Evaluates to False. c = None 54. booleans a = True b = False 55. sequences ● lists ● tuples ● sets 56. lists Hold sequences. How would we find out the attributes & methods of a list? 57. lists >>> dir([]) ['__add__', '__class__', '__contains__',... '__iter__',... '__len__',... , 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] 58. lists >>> >>> >>> >>> >>> >>> [1, a = [] a.append(4) a.append('hello') a.append(1) a.sort() # in place print a 4, 'hello'] 59. lists How would we find out documentation for a method? 60. lists help function: >>> help([].append) Help on built-in function append: append(...) L.append(object) -- append object to end 61. List methods ● l.append(x) Insert x at end of list ● l.extend(l2) Add l2 items to list ● l.sort() In place sort 62. List methods (2) ● l.reverse() Reverse list in place ● l.remove(item) Remove first item found ● l.pop() Remove/return item at end of list 63. Dictionaries 64. dictionaries Also called hashmap or associative array elsewhere >>> >>> >>> >>> >>> 10 age = {} age['george'] = 10 age['fred'] = 12 age['henry'] = 10 print age['george'] 65. dictionaries (2) Find out if 'matt' in age >>> 'matt' in age False 66. in statement Uses __contains__ dunder method to determine membership. (Or __iter__ as fallback) 67. .get >>> print age['charles'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError?: 'charles' >>> print age.get('charles', 'Not found') Not found 68. deleting keys Removing 'charles' from age >>> del age['charles'] 69. deleting keys del not in dir. .pop is an alternative 70. Functions 71. functions def add_2(num): """ return 2 more than num """ return num + 2 five = add_2(3) 72. functions (2) ● def ● function name ● (parameters) ● : + indent ● optional documentation ● body ● return 73. whitespace Instead of { use a : and indent consistently (4 spaces) 74. whitespace (2) invoke python -tt to error out during inconsistent tab/space usage in a file 75. default (named) parameters def add_n(num, n=3): """default to adding 3""" return num + n five = add_n(2) ten = add_n(15, -5) 76. __doc__ Functions have docstrings. Accessible via .__doc__ or help 77. __doc__ >>> def echo(txt): ... "echo back txt" ... return txt >>> help(echo) Help on function echo in module __main__: <BLANKLINE> echo(txt) echo back txt <BLANKLINE> 78. naming ● lowercase ● underscore_between_words ● don't start with numbers ● verb See PEP 8 79. Conditionals 80. conditionals if grade > 90: print "A" elif grade > 80: print "B" elif grade > 70: print "C" else: print "D" 81. Remember the colon/whitespace! 82. Booleans a = True b = False 83. Comparison Operators Supports (>, >=, <, <=, ==, !=) >>> 5 > 9 False >>> 'matt' != 'fred' True >>> isinstance('matt', basestring) True 84. Boolean Operators and, or, not (for logical), &,

85. Boolean note Parens are only required for precedence if (x > 10): print "Big" same as if x > 10: print "Big" 86. Chained comparisons if 3 < x < 5: print "Four!" Same as if x > 3 and x < 5: print "Four!" 87. Iteration 88. iteration for number in [1,2,3,4,5,6]: print number for number in range(1, 7): print number 89. range note Python tends to follow half-open interval ([start,end)) with range and slices. ● end - start = length ● easy to concat ranges w/o overlap 90. iteration (2) Java/C-esque style of object in array access (BAD): animals = ["cat", "dog", "bird"] for index in range(len(animals)): print index, animals[index] 91. iteration (3) If you need indices, use enumerate animals = ["cat", "dog", "bird"] for index, value in enumerate(animals): print index, value 92. iteration (4) Can break out of nearest loop for item in sequence: # process until first negative if item < 0: break # process item 93. iteration (5) Can continue to skip over items for item in sequence: if item < 0: continue # process all positive items 94. iteration (6) Can loop over lists, strings, iterators, dictionaries... sequence like things: my_dict = { "name": "matt", "cash": 5.45} for key in my_dict.keys(): # process key for value in my_dict.values(): # process value for key, value in my_dict.items(): # process items 95. pass pass is a null operation for i in # do pass range(10): nothing 10 times 96. Hint Don't modify list or dictionary contents while looping over them 97. Slicing 98. Slicing Sequences (lists, tuples, strings, etc) can be sliced to pull out a single item my_pets = ["dog", "cat", "bird"] favorite = my_pets[0] bird = my_pets[-1] 99. Negative Indexing Proper way to think of [negative indexing] is to reinterpret a[-X] as a[len(a)-X] @gvanrossum 100. Slicing (2) Slices can take an end index, to pull out a list of items my_pets = ["dog", "cat", "bird"] # a list cat_and_dog = my_pets[0:2] cat_and_dog2 = my_pets cat_and_bird = my_pets[1:3] cat_and_bird2 = my_pets[1:] 101. Slicing (3) Slices can take a stride my_pets = ["dog", "cat", "bird"] # a list dog_and_bird = [0:3:2] zero_three_etc = range(0,10) [::3] 102. Slicing (4) Just to beat it in veg = "tomatoe" correct = veg tmte = veg[::2] eotamot = veg[::-1] 103. File IO 104. File Input Open a file to read from it (old style): fin = open("foo.txt") for line in fin: # manipulate line fin.close() 105. File Output Open a file using 'w' to write to a file: fout = open("bar.txt", "w") fout.write("hello world") fout.close() 106. Always remember to close your files! 107. closing with with implicit close (new 2.5+ style) with open('bar.txt') as fin: for line in fin: # process line 108. Classes 109. Classes class Animal(object): def __init__(self, name): self.name = name def talk(self): print "Generic Animal Sound" animal = Animal("thing") animal.talk() 110. Classes (2) notes: ● object (base class) (fixed in 3.X) ● dunder init (constructor) ● all methods take self as first parameter 111. Classes(2) Subclassing class Cat(Animal): def talk(self): print '%s says, "Meow!"' % (self.name) cat = Cat("Groucho") cat.talk() # invoke method 112. Classes(3) class Cheetah(Cat): """classes can have docstrings""" def talk(self): print "Growl" 113. naming ● CamelCase? ● don't start with numbers ● Nouns 114. Debugging 115. Poor mans print works a lot of the time 116. Remember Clean up print statements. If you really need them, use logging or write to sys.stdout 117. pdb import pdb; pdb.set_trace() 118. pdb commands ● h - help ● s - step into ● n - next ● c - continue ● w - where am I (in stack)? ● l - list code around me ... "
, and ^ (for bitwise) >>> x = 5 >>> x < -4 or x > 4 True

---

example Hoon code:

" ...FizzBuzz?. Each line is commented with its number:

:gate end/atom :: 1 :var count 1 :: 2 :loop :: 3 :cast (list tape) :: 4 :if =(end count) :: 5 ~ :: 6 :cons :: 7 :if =(0 (mod count 15)) :: 8 "FizzBuzz?" :: 9 :if =(0 (mod count 5)) :: 10 "Fizz" :: 11 :if =(0 (mod count 3)) :: 12 "Buzz" :: 13 (pave :wrap(count)) :: 14 :moar(count (add 1 count)) :: 15

...

Hoon is a functional language. FizzBuzz? is usually defined as a side effect, but Hoon has no side effects. This code will make a list of strings, not print a list of strings.

Line 1 defines a function of one argument, end, an unsigned integer.

Line 2 declares a variable, count, with initial value 1.

Line 3 begins a loop.

Line 4 casts the product of the loop to a list of tape (string as a character list).

Line 5 checks if count equals end. If so, line 6 (and the whole loop) produces the value ~, null, the empty list. If not, line 7 begins an ordered pair.

The head of the pair is "FizzBuzz?", or "Fizz", or "Buzz", if the respective tests hit. If not, line 14 wraps a runtime type around count, then prints the type-value pair to a string (like C sprintf()). This string is the first item in the output list.

The tail of the pair is line 15, which repeats the loop (like Clojure recur), with count incremented. This list of strings is the rest of the output list. "

[1]

---

" For some extra dependently typed fun, check out ATS and Dafny.

ATS is aimed at system programming, and if you think Idris has a steep learning curve, you'll need belaying for ATS. And, the language is horrible. But it's really mind expanding to see it in action.

Dafny is a really basic language with support for Hoare/Dijkstra verification. It's completely unlike the type system model. "

---

some problems with Linux:

to3m 6 days ago

parent flag favorite on: Remotely Exploitable Type Confusion in Windows 8, ...

1. Signals are bad. All the bad bits of IRQs, and you're not even working in assembly language, so they're twice as hard. Just say no.

2. The forking model is seductive, but wrong-headed. It's hard to make the file descriptor inheritance behave correctly, and it means the memory requirements are unpredictable (due to the copy-on-write pages)

3. Readiness I/O is not really the right way to do things, because there are obvious race conditions, and the OS can't guarantee one thread woken per pending operation (because it has no idea which threads will do what). Also, the process owns the buffer, which really limits what the OS can do... it needs to be able to own the buffer for the duration of the entire operation for best results, so it can fill it on any ready thread, map the buffer into the driver's address space, etc.

4. Poor multithreading primitives. This really annoyed me... like, you've got a bunch of pthreads stuff, but it doesn't interact with select & co. The Linux people aren't dumb, so they give you eventfd - but there's no promise of single wakeup! NT wakes up one thread per increment, and the wakeup atomically decrements the semaphore; Linux wakes up every thread waiting on the semaphore, and they all fight over it, because there's no other option.

(I'm just ignoring POSIX semaphores entirely, because they don't let you wait on them with select/poll/etc. in the first place.)

(Perhaps this and #3 ought to be the same item, because they are related. And the end result is that you need to use non-blocking IO for everything... but the non-blocking IO is crippled, because it still has to copy out into the caller's buffer. It's just a more inconvenient programming model, for no real benefit.)

I guess it just boils down to what you want: a beautifully polished turd, or a carefully engineered system assembled from turds.

Sir_Cmpwn 6 days ago [-]

Thanks for humoring me. For what it's worth, I agree with you on all of these points, but I still fall strongly in favor of POSIX over Windows.

reply

caf 6 days ago [-]

Using signals in the ye olde UNIX fashion is bad. However, that was entirely fixed with the advent of POSIX threads: block all signals in all threads with sigprocmask(), and have a dedicated signal-handling thread that loops around on sigwaitinfo(). That thread then handles signals entirely synchronously, notifying other parts of the program using usual inter-thread communication.

reply

comex 5 days ago [-]

> The Linux people aren't dumb, so they give you eventfd - but there's no promise of single wakeup! NT wakes up one thread per increment, and the wakeup atomically decrements the semaphore; Linux wakes up every thread waiting on the semaphore, and they all fight over it, because there's no other option.

You can get Linux to only wake up one thread using epoll and either EPOLLEXCLUSIVE or EPOLLONESHOT.

Though I don't really understand why you'd want to wait on a semaphore and other waitables at the same time… probably this is just my Unix bias/lack of Windows experience showing.

reply

marcosdumay 5 days ago [-]

> Though I don't really understand why you'd want to wait on a semaphore and other waitables at the same time…

This. I probably also lack some specific kind of experience because I never understood why you would lock a lot of threads on a semaphore, and only want one of them to execute after a signal.

I just never saw the use case for that. Yet people complain about it a lot.

reply

mh8h 5 days ago [-]

I'm curious, given all these limitations in POSIX, what are some examples of software that do better on Windows because of these more advanced OS features?

reply

ptx 5 days ago [-]

This experimental Python fork depends on IOCP (and other Windowsy things) to achieve better performance: http://pyparallel.org/

reply

---

" ... Where I like x86 and where I don't like RISC-V is that x86 doesn't try to be perfect but rather to adapt over time. RISC-V tries to be perfect and indeed eschews many of the bad RISC ideas from the past (register windows, branch delay slots, tagged integers, ...) while then pig headedly avoiding an obvious feature shared by both x86 and ARM, condition codes. I've read their argument and found it unconvincing. Original ARM had way too much condition code support. I think ARMv8 strikes a nice balance that RISC-V should have followed.

The HP+Intel Itanium effort allowed AMD to propose their AMD64 extensions. That's been quite successful. I wish they'd taken the opportunity to trim more cruft. When ARM went 64b with ARMv8, they took that opportunity and the result is quite clean. I prefer it to RISC-V although I haven't written any RISC-V assembly.

ARMv8 tries to be a good instruction set architecture. To me, RISC-V tries to be the platonic ideal RISC ISA. I'll go with good.

reply

microcolonel 7 days ago [-]

Yeah, I agree that condition codes (and offset loads) are features, not bugs in x86 and ARM; also ARMv8 shows an effort to reduce the number of instructions which can respond to condition codes. Chris Celio has talked about some interesting ways to make up for the lack of these two features, and it seems quite convincing. If you're using the compressed instruction set (which all desktop/workstation type RISC-Vs and most microcontrollers support), then the decoder can implicitly fuse the add and the load, or various forms of conditions, and treat them as a single operation. AFAIK, the compiler backends already try to order the instructions to exploit this.

And yeah, I'm not utterly convinced by any argument about "purity" in ISAs, but in this case there's no question that it has helped a wider variety of people develop interesting and competitive chips in less time. "

---

dom0 7 days ago [-]

OpenSPARC? is GPL. And OpenSPARC? means the T1/T2 designs (high throughput, very low single-threaded performance) which are useless outside their niche.

reply

---

FullyFunctional? 8 days ago [-]

(Public service announcement: https://riscv.org/forum/)

Others have the SiFive? chip, but if you want to boot Linux then your best option currently is running Rocket on an FPGA kit. I expect that we'll soon have more options. If you just want to play around, then I'd recommend Spike or Fabrice's https://bellard.org/riscvemu/

my note: riscvemu js demo running 64-bit Linux: https://bellard.org/riscvemu/js/

---

geodel 10 hours ago [-]

Well this looks like going to push Kotlin in big league. I remember scala enthusiasts made big noise in last few years to have scala as officially supported language. But Google seems to prefer a closer relationship with Jetbrains.

reply

izacus 7 hours ago [-]

The newest version of Scala (2.12) requires a JVM with Java 8 feature compatibility which makes it unusable on Android devices. Google would literally be stuck supporting an obsolete version of a language that's not developed... or restrict the use of it only to Android O and newer making it dead on arrival.

Kotlin compiler generates code that's runnable on JVMs supporting Java 6, which makes it work on pretty much any Android device, even running older Androids.

Scala standard library is also huge and pretty much immediately hits the 64K method limit of DEX files forcing you to use the very slow proguard compilation step when running it. It also has issues with interoperability with existing Java 6 code.

All in all, Scala is a terrible value proposition in comparison to Kotlin which was built from ground up to modernize programming while still keeping full compatibility with Java 6 code and JVMs stuck on Java 6 language level.

reply

---

fauigerzigerk 5 hours ago [-]

What's the advantage of extension functions compared to plain functions?

  fun String.shout() = this + "!!!"
  fun shout(s: String) = s + "!!!"

Looks pretty much the same to me. Extension functions use static dispatch so what's the point of using member syntax?

Also, extension functions can be overwritten by a member function with the same signature. That seems quite fragile to me considering the class and the extension function very likely have different authors.

That said, I don't know Kotlin very well. So perhaps you can set me straigt on any misconceptions I may have.

reply

skrebbel 3 hours ago [-]

Besides what Larrikin said, discoverability. Discoverability is the killer feature of languages designed for IDE support that you just won't understand if you haven't seen it. It's a big reason of why Kotlin beats Scala in practice, IMO (1).

I code Elixir a lot these days and spend a lot of time looking at hexdocs.pm and occasional library source code. With Kotlin or C#, this is seldomly necessary, because the IDE's autocomplete tells you everything you can do with this object. It doesn't guess, it knows. If it's in the list, you can do it, if it's not, you can't.

Now, if I have a string object called "str", and I write "str.", I want to see a list of everything I can do with it. But a MyStringUtils?.shout() is never in that list, because it does not come after the dot.

With extension functions, this becomes possible with userland extensions to existing classes and interfaces. All you need is a single import on top, and good IDEs (eg. visual studio) can also auto-import that one if you use a function from it once.

(1) Last I tried, Scala was too slow to compile to provide 100% perfect autocomplete within a few milliseconds. IntelliJ? did some Python-esque guesswork to mitigate that, but that effectively reduces the feature to "save me some keystrokes", i.e. not very useful. Maybe this has been fixed since.

reply

Larrikin 4 hours ago [-]

I use extension functions on classes I don't own to add functionality I think the class should have had or would be extremely useful for my project if a certain type of class had the functionality. Your example would require a static utility class in Java or an object in Kotlin to use every where, the extension functions can just be inside of a kotlin file.

So the difference would be in Kotlin

  object StringUtilClass() {
    fun shout(s: String) = s + "!!!""
  }
  import StringUtilClass.*
  StringUtilClass.shout("I'm mad")

vs

  fun String.shout() = this + "!!!"
  import StringExtensions.*
  "I'm mad".shout()

Kotlin doesn't always add brand new functionality, it also strives to make it faster to read and write code.

reply

fauigerzigerk 3 hours ago [-]

That surprises me. I would have thought that you could do this in Kotlin just as you can in Java with static import:

  import StringUtilClass.*
  shout("I'm mad")

reply

Larrikin 2 hours ago [-]

Personally I find that less clear where shout is coming from and how to use it. It would also make autocomplete less useful as mentioned

reply

cromwellian 16 hours ago [-]

I don't think it's Java fault per se, just the API design. Java8 streams, RxJava?, BufferKnife? injection, Guava, etc are pretty nice to use, especially in combination with Java8. There's no async/await, but if you use ReactiveX?, you don't really need it.

Kotlin looks very nice, I'm just pointing out that if the Android View/Fragment lifecycle design is an issue, language design isn't the cause or solution, and most likely, you will need a middleware/facade to mitigate it.

reply

---

barrkel 20 hours ago [-]

Other language built around IDE support: Delphi.

The compiler was built with callbacks to provide code completion; it runs in process, as a DLL, as part of the IDE.

No accident that Hejlsberg also design C#, and innovated further with TypeScript?'s language server. He wrote the original Turbo Pascal (IDE + Compiler in the same executable) in assembler, so he's been building IDE + language combos all his life.

reply

comboy 20 hours ago [-]

Oh Delphi.. every time I fight with CSS and think about how easy making GUI apps used to be almost 20(sic!) years ago, I feel like something went wrong.

Mandatory: https://www.youtube.com/watch?v=8pTEmbeENF4

reply

marktangotango 19 hours ago [-]

So did Delphi handle dynamically resizing and positioning layouts? My impression is all the old highly productive gui languages (Delphi, Visual Basic, ...) used absolute positioning. Personally I'd rather have a more complex gui framework (css, swing, wpf) that handles positioning than to be forever cursed tweaking pixel width, height, x, y values.

reply

Joeri 15 hours ago [-]

It has anchor layout, flow layout, table layout, etc... I have typically found it easier to do the layout I wanted in delphi than CSS. The only annoying thing is that the visual designer has no undo, which you really miss when doing exploratory designs.

CSS 2 really is terrible. There's a few things in CSS 3 that make it passable, but overall I consider it a failed layout system which needs more workarounds than it provides solutions.

reply

bitL 18 hours ago [-]

Yes, if you set anchors on each component you wanted to be resizable (more specifically, all four sides could have had an independent anchor).

reply

flukus 17 hours ago [-]

Same with winforms. I'm not sure if it was added at some point or always there, if it was always there I wish I knew about it a lot sooner.

reply

JustSomeNobody? 15 hours ago [-]

>... than to be forever cursed tweaking pixel width, height, x, y values.

Inevitably, this is what CSS work devolves to, though.[0]

[0] Pixel twiddling

reply

flukus 19 hours ago [-]

I had to do maintenance on an old winforms app recently, it's insane how simple it is to develop with, how quickly it starts up and how quickly it show users the data they want. I signed myself up as the project maintainer.

And even that is an incredibly bloated technology compared to delphi.

reply

iamcurious 6 hours ago [-]

For those who want to see how Delphi GUI design is: https://www.youtube.com/watch?v=BRMo5JSA9rw

reply

---

noir_lord 8 hours ago [-]

My all time favourite languages are (in descending order), Delphi, Turbo Pascal and C#.

It's not a co-incidence that I moved to TypeScript? recently and am absolutely loving it, it feels like JS but engineered.

reply

twoquestions 7 hours ago [-]

Typescript is nice, I just wish it inferred types as well as F#.

reply

---

 kasey_junk 9 hours ago [-]

For certain classes of problems the JVM just cannot be beat. Its a phenomenal bit of tech that laps the competition, especially with regard to large data sets, concurrency support, and instrumentation. Unfortunately, Java the language is fairly painful to work in (less so every release but still). Kotlin makes that particular problem less of an issue.

Even in plain Java though, your description of "the vast, lumbering Java engine cranking slowly and chugging and masses of XML configuration up the wazoo for everything" is largely only applicable in Enterprise software. Modern Java shops tend to eschew all those things and have for quite some time.

reply

xiaoma 8 hours ago [-]

Could you dig in a bit more into how the JVM laps the Erlang VM in terms of concurrency support and instrumentation?

reply

kasey_junk 7 hours ago [-]

Erlang is probably the closest competitor to the JVM and is a fine VM in its own right (especially for classes of concurrency problems that can operate independently).

But if you are dealing with a big interconnected data set that also needs to be concurrently accessed the Erlang memory model doesn't work as well as the JVM one.

For the kind of concurrency model that Erlang is offering it is great, but the JVM offers more variety, so that you can craft your concurrency to your problem instead of being shoe horned into 1 model.

I'd add that the commercial offerings for the JVM (and alternative JVMs like Zing) make the ecosystem more rich than the Erlang one as well.

Finally, I'd say that Erlang suffers from a similar problem to Java, that is, the VM is without peer for certain classes of problem but the ergonomics of the language make people choose other solutions. I think that is a shame as I'd like to see more solutions built on top of BEAM.

I should note, I've not programmed on BEAM for production purposes, only for small proje

---

BJanecke 15 hours ago [-]

Kotlin is really nice and I am very happy to have more than one great/fun/productive language however I feel like mentioning typescript might be worthwhile (yes I know it's "just" a superset of JS and you have a personal gripe with whatever you think JS is but hear me out).

   ```
    function pluck<T>(key: keyof T, from: T[]) {
       return from.map(item => item[key]);
     }
   ```

[edit] Formatting

reply

---

on kotlin:

" It's safer than Java. It provides built-in support for many things that are handled in Java these days with annotation processors -- override checking, nullability analysis, etc. It also has safer numeric conversion rules, and although I'm not sure I like them, I have to appreciate how they force me to think about all my number representations. ... It's succinct. On average I find it to be about 5-10% shorter than the equivalent Jython code (which is sort of my gold standard), while remaining more readable and far more typesafe.

It's practical. Kotlin allows multiple classes per file, top-level functions, operator overloading, extension methods, type aliasing, string templating, and a whole bunch of other bog-standard language features that for whatever reason Java just never adopted even though everyone wanted them. "

---

some of Yegge's (old) complaints about Clojure:

also, compliants about Java: the community resists using: inheritance, arrays, static methods, constructors (?!)

[2]

---

Hickey explains why circular dependencies are not allowed in Clojure:

richhickey 2220 days ago

parent favorite on: Steve Yegge v. Rich Hickey re: "Clojure just needs...

The issue is not single-pass vs multi-pass. It is instead, what constitutes a compilation unit, i.e., a pass over what?

Clojure, like many Lisps before it, does not have a strong notion of a compilation unit. Lisps were designed to receive a set of interactions/forms via a REPL, not to compile files/modules/programs etc. This means you can build up a Lisp program interactively in very small pieces, switching between namespaces as you go, etc. It is a very valuable part of the Lisp programming experience. It implies that you can stream fragments of Lisp programs as small as a single form over sockets, and have them be compiled and evaluated as they arrive. It implies that you can define a macro and immediately have the compiler incorporate it in the compilation of the next form, or evaluate some small section of an otherwise broken file. Etc, etc. That "joke from the 1980's" still has legs, and can enable things large-unit/multi-unit compilers cannot. FWIW, Clojure's compiler is two-pass, but the units are tiny (top-level forms).

What Yegge is really asking for is multi-unit (and larger unit) compilation for circular reference, whereby one unit can refer to another, and vice versa, and the compilation of both units will leave hanging some references that can only be resolved after consideration of the other, and tying things together in a subsequent 'pass'. What would constitute such a unit in Clojure? Should Clojure start requiring files and defining semantics for them? (it does not now)

Forward reference need not require multi-pass nor compilation units. Common Lisp allows references to undeclared and undefined things, and generates runtime errors should they not be defined by then. Clojure could have taken the same approach. The tradeoffs with that are as follows:

1) less help at compilation time 2) interning clashes

While #1 is arguably the fundamental dynamic language tradeoff, there is no doubt that this checking is convenient and useful. Clojure supports 'declare' so you are not forced to define your functions in any particular order.

  1. 2 is the devil in the details. Clojure, like Common Lisp, is designed to be compiled, and does not in general look things up by name at runtime. (You can of course design fast languages that look things up, as do good Smalltalk implementations, but remember these languages focus on dealing with dictionary-carrying objects, Lisps do not). So, both Clojure and CL reify names into things whose addresses can be bound in the compiled code (symbols for CL, vars for Clojure). These reified things are 'interned', such that any reference to the same name refers to the same object, and thus compilation can proceed referring to things whose values are not yet defined.

But, what should happen here, when the compiler has never before seen bar?

    (defn foo [] (bar))

or in CL:

    (defun foo () (bar))

CL happily compiles it, and if bar is never defined, a runtime error will occur. Ok, but, what reified thing (symbol) did it use for bar during compilation? The symbol it interned when the form was read. So, what happens when you get the runtime error and realize that bar is defined in another package you forgot to import. You try to import other-package and, BAM!, another error - conflict, other-package:bar conflicts with read-in-package:bar. Then you go learn about uninterning.

In Clojure, the form doesn't compile, you get a message, and no var is interned for bar. You require other-namespace and continue.

I vastly prefer this experience, and so made these tradeoffs. Many other benefits came about from using a non-interning reader, and interning only on definition/declaration. I'm not inclined to give them up, nor the benefits mentioned earlier, in order to support circular reference.

Rich

steve_yegge 2220 days ago [-]

Most of the user annoyance vanishes if declare were to support qualified names: (declare other-namespace/symbol). Is there a technical limitation here?

-steve

richhickey 2220 days ago [-]

One problem is what to do if the other-namespace doesn't already exist. It would have to be created, and that initialization is unlikely to be the same as the declared one. Possibly follow-on effects when it is subsequently required. The other option, with similar issues, is to allow fully qualified references to non-existent vars in code.

billmcneale 2219 days ago [-]

If it doesn't already exist, then you issue a compilation error. Better then than the way it works today, IMO.

richhickey 2220 days ago

parent favorite on: Steve Yegge v. Rich Hickey re: "Clojure just needs...

The issue is not single-pass vs multi-pass. It is instead, what constitutes a compilation unit, i.e., a pass over what?

Clojure, like many Lisps before it, does not have a strong notion of a compilation unit. Lisps were designed to receive a set of interactions/forms via a REPL, not to compile files/modules/programs etc. This means you can build up a Lisp program interactively in very small pieces, switching between namespaces as you go, etc. It is a very valuable part of the Lisp programming experience. It implies that you can stream fragments of Lisp programs as small as a single form over sockets, and have them be compiled and evaluated as they arrive. It implies that you can define a macro and immediately have the compiler incorporate it in the compilation of the next form, or evaluate some small section of an otherwise broken file. Etc, etc. That "joke from the 1980's" still has legs, and can enable things large-unit/multi-unit compilers cannot. FWIW, Clojure's compiler is two-pass, but the units are tiny (top-level forms).

What Yegge is really asking for is multi-unit (and larger unit) compilation for circular reference, whereby one unit can refer to another, and vice versa, and the compilation of both units will leave hanging some references that can only be resolved after consideration of the other, and tying things together in a subsequent 'pass'. What would constitute such a unit in Clojure? Should Clojure start requiring files and defining semantics for them? (it does not now)

Forward reference need not require multi-pass nor compilation units. Common Lisp allows references to undeclared and undefined things, and generates runtime errors should they not be defined by then. Clojure could have taken the same approach. The tradeoffs with that are as follows:

1) less help at compilation time 2) interning clashes

While #1 is arguably the fundamental dynamic language tradeoff, there is no doubt that this checking is convenient and useful. Clojure supports 'declare' so you are not forced to define your functions in any particular order.

  1. 2 is the devil in the details. Clojure, like Common Lisp, is designed to be compiled, and does not in general look things up by name at runtime. (You can of course design fast languages that look things up, as do good Smalltalk implementations, but remember these languages focus on dealing with dictionary-carrying objects, Lisps do not). So, both Clojure and CL reify names into things whose addresses can be bound in the compiled code (symbols for CL, vars for Clojure). These reified things are 'interned', such that any reference to the same name refers to the same object, and thus compilation can proceed referring to things whose values are not yet defined.

But, what should happen here, when the compiler has never before seen bar?

    (defn foo [] (bar))

or in CL:

    (defun foo () (bar))

CL happily compiles it, and if bar is never defined, a runtime error will occur. Ok, but, what reified thing (symbol) did it use for bar during compilation? The symbol it interned when the form was read. So, what happens when you get the runtime error and realize that bar is defined in another package you forgot to import. You try to import other-package and, BAM!, another error - conflict, other-package:bar conflicts with read-in-package:bar. Then you go learn about uninterning.

In Clojure, the form doesn't compile, you get a message, and no var is interned for bar. You require other-namespace and continue.

I vastly prefer this experience, and so made these tradeoffs. Many other benefits came about from using a non-interning reader, and interning only on definition/declaration. I'm not inclined to give them up, nor the benefits mentioned earlier, in order to support circular reference.

Rich

steve_yegge 2220 days ago [-]

Most of the user annoyance vanishes if declare were to support qualified names: (declare other-namespace/symbol). Is there a technical limitation here?

-steve

richhickey 2220 days ago [-]

One problem is what to do if the other-namespace doesn't already exist. It would have to be created, and that initialization is unlikely to be the same as the declared one. Possibly follow-on effects when it is subsequently required. The other option, with similar issues, is to allow fully qualified references to non-existent vars in code.

billmcneale 2219 days ago [-]

If it doesn't already exist, then you issue a compilation error. Better then than the way it works today, IMO.

---

Yegge on why VMs:

" So I was in this discussion at the very end of the last day, where the Apple LLVM guy Chris [Lattner] was hosting a talk on dynamic languages running on different VMs. And there was the Smalltalk Squeak guy there, and there was Charles Nutter for JRuby and representing the JVM. John Lam was there for IronRuby? and CLR, and there were the Parrot people. I can't even remember them all, but the whole room was packed with the VM implementors of the VMs today, and people who are implementing languages on top of them.

...

And Chris, well, he let everybody go around the room and talk about why their VM was the best. And they were all right! That's the weird thing: every single one of them was right. Their VM was the best for what they wanted their VM to do.

Like, Smalltalk [Squeak]'s VM was the best in the sense of being the purest, and it was the cleanest. Whereas the Java one was the best because, you know, it has Java! Everybody's was the best. Parrot's was the best because it was vaporware. Ha! Ha, ha ha. Sorry guys.

So! He [Chris] asked this really innocent question. He goes, "You know, I don't really know much about this stuff..."

Which is bad, you know. When somebody says that to you at Foo Camp, it means they're settin' you up.

He says, "So how do these languages talk to each other?"

And the room just erupted! It was chaos. All these people are like, "Oh, it's easy!" And the rest of them are like "No, it's hard!" And they're arguing, and arguing, and arguing. They argued for an hour.

And then they stood up, still arguing, and they kept talking about it, heading into the dinner tent. And they sat down, going at it for like three hours.

It was chaos.

Because some people were saying, "Well, you know, if Ruby's gonna call Python, well, uh, you just call, right? You just share the same stack, right?"

And the others are like, "Well, what about different calling conventions? What if they support optional vs. non-optional arguments? What if they support default arguments? What about the threading model? What about the semantics of, you know, the this pointer? What about all this stuff?"

And they're like (waving hands) "Ooooh, we'll gloss over it, gloss over it, smooth it over." And the reply is: "You can't. This is fundamental. These languages work differently!"

And oh my god, it was really interesting. And it was also very clear that it's ten years of research and implementation practice before they get this right. Before you'll be able to have a stack of calls, where you're calling from library to function, library to function in different languages.

So today, VMs are good for interoperability, but you've gotta use a bridge. Whether it's JRuby, or Jython, or Rhino, they provide a set of APIs — you know about javax.script, right? It's this new thing introduced to the JDK, where they try to formalize just a couple of APIs around how you call the scripting language from your language... you know, it's a sort of "reverse foreign-function interface". And then how they call each other, maybe.

But it's all done through... kind of like serialization. You marshal up your parameters as an array of arguments, and it's a heavyweight call that goes over [to the script runtime] and comes back, and it's like... it's a pain! You don't want that. But today, that's kind of what we're stuck with.

At least we have that, though, right? I mean, try having Ruby call Python today, and they have different FFIs. You can do it, but you definitely want the VM's help.

So, Walter, that's why you need VMs. "

---

"...Common Lisp, which has become the ultimate "no" language -- its spec has been cast in stone for a quarter century now. No threads, no module system (beyond packages), no new collection types, etc. etc. etc."

---

" I mean, like, if you program in Ruby, say, you know that you can actually change the way the metaclass produces objects. So if you want it to be a singleton, or you want it to meet certain... you want it to be a Mock object, you just replace the new function on the fly, and you've got yourself a Mock constructor, right?

But Java's set in stone! So they use factories, which leads to this proliferation of classes. And you have to use a "Dependency Injection Framework" to decouple things, right?

And it's just, like, (panting)... We were doing business logic early on in Java. When Java came out, it was like: "Ooooh, it's a lot easier to write C code", basically, or C++. Rather than focusing on your memory allocation strategy, or which of your company's six conflicting string classes you're gonna use, you get to focus on "business logic".

But unfortunately that only took you so far. Now you're focusing on Mock object frameworks. It [Java] only took you a little farther.

Now I swear, man, doing Mock objects in Rhino is so easy! It's easier, even, than in JRuby or in Jython, because JavaScript? has JSON. I didn't even know, like, the name of it when I started doing this, right? But JSON... I've gotta show you guys this. This is so cool. (flipping through slides) "

---

a slide from a talk [3] on Rhino, JS on the JVM with some extra features

this feature is supposedly good for making mock objects for unit testing:

Using Java Classes and Interfaces

var t = new Thresh{new Runnable() {run: function(

t.start()
print('hello!') )}}

hello!

obj = {run: function(

print('hi') )}

[object Object]

new Thread(new Runnable(obj)).start()

hi

---

"XML is better if you have more text and fewer tags. And JSON is better if you have more tags and less text." [4]

---

"JavaScript?...has borrowed some stuff from Python in JavaScript? 1.7: yield, Array comprehensions, destructuring assignment. "

---

blhack 1 hour ago [-]

I spent almost 10 years doing IT for a company whose backend was based entirely on as/400. If you've ever used a system like that, I'm sure you know where this is going...

The console's that the front-desk or clerical users used every day had a steep learning curve. It was something that you would definitely not be able to walk up to and just intuit.

However, once you figured it out, there is never going to be a faster UI that you are ever going to experience in your life until we figure out direct BCI stuff.

It was funny watching the new people come on board and insist that we should change the UI to something with a mouse (probably web based). They had no idea that more immediately intuitive was actually a step backwards.

My point is that just because something has a steep learning curve, that doesn't necessarily mean that it's a bad design.

reply

jakub_g 1 hour ago [-]

I work for a reservation systems company (a GDS) that is used by thousands of travel agencies. Of course, since the system was created 30 years ago, you were only able to create reservation with a text-based interface at the time, with short commands, inconsistent and complex flows to do some non-trivial things etc. So it's despised by newcomers because learning curve is steep.

However, the company has been building new web-based solutions for a while, but all of them have so called "cryptic mode" where you can still directly input the commands, as it is order of magnitude faster, mandatory feature for experienced old-timer travel agents.

reply

Brotkrumen 48 minutes ago [-]

Altea Amadeus.

And all the three big GDS need to be thrown into a fire. "Oh you want to add a person to the PNR? Well tough luck! Not a use case we handle!"

reply

---

http://data.stackexchange.com/stackoverflow/query/53109/questions-with-most-views

How to undo last commit(s) in Git? How to convert a String to an int in Java? How to delete a Git branch both locally and remotely? How to check whether a string contains a substring in JavaScript?? How to redirect to another webpage in JavaScript?/jQuery? How to remove a particular element from an array in JavaScript?? How to revert Git repository to a previous commit? How to create an HTML button that acts like a link? How to check whether a checkbox is checked in jQuery? How to horizontally center a

in another ? How to declare and initialize an array in Java? How to find all files containing specific text on Linux? How to generate random integers within a specific range in Java? For-each over an array in JavaScript?? How to check out a remote Git branch? How to UPDATE from a SELECT in SQL Server?

---

" “Simple Made Easy” has instilled in many minds the notion that simple and easy are two sides of a spectrum, that they are necessarily at odds. But simple/complex and easy/hard are separate dimensions. While there’s great merit in striving for simplicity, it would be a mistake to disregard ease. I think as Clojure programmers, as library authors, we have been too focused on the reductionist, on building solid parts. ... Every tool, every library forms an interface, a language that people must first master to convey their intent. Pay as much attention to designing these interfaces as you would designing their functional internals. This is the face with which your code looks upon the world. Make it smile with its eyes.

To quote Laozi,

    People usually fail when they are on the verge of success.
    So give as much care to the end as to the beginning;
    Then there will be no failure.... And Rubyists, you too have something to gain from this exchange. Yes, you’ve been hearing for years of the benefits of immutable data, the elegance of pure functions. "

---

Cieplak 10 hours ago [-]

Modern C++ can be very pythonic. Still not as easy as writing Java in IntelliJ? but CLion is becoming quite good (if you succumb to CMake). People write shit code in every language; C++ has my favorite abstraction to performance ratio.

http://preshing.com/20141202/cpp-has-become-more-pythonic

reply

oblio 8 hours ago [-]

As a non-C++ coder there are two things that "scare" me about C++ (ok, maybe not scare, but are definitely big turn offs):

There's also the compilation speed, but as far as I know there are workarounds for that.

These things are, if not unsolvable in C++, at least many years away from being available.

Maybe an experienced C++ coder can destroy my preconceptions :)

reply

humanrebar 5 hours ago [-]

> Maybe an experienced C++ coder can destroy my preconceptions :)

https://kukuruku.co/post/undefined-behavior-and-fermats-last...

https://stackoverflow.com/questions/367633/what-are-all-the-...

There are tricks and tools to avoid undefined behavior, but I find that most C++ engineering orgs don't prioritize the tooling (linters, UB sanitizers, etc.) needed to let engineers do this productively. Consequently, a lot of writing good C++ involves detailed coding standards and/or very detail-oriented gurus poring over code reviews.

reply

---

https://www.qualcomm.com/news/onq/2017/04/13/artificial-intelligence-tech-snapdragon-835-personalized-experiences-created

---

Python 'chained conditionals' eg:

if x < y: print("x is less than y") elif x > y: print("x is greater than y") else: print("x and y must be equal")

---

evincarofautumn 83 days ago [-]

I’ve been working on a statically typed concatenative programming language, Kitten[1], off and on for a few years now. I plan to do an early release this year.

I started working on the language to bring an elegant compositional style to low-level high-performance programming, in the form of a simple language that admits powerful tooling for program editing and visualisation. I also wanted to address usability concerns with stack-based languages (e.g., by allowing infix operators). As I’ve spent time in industry, I’ve begun to treat it as a way to address my gripes with C, C++, and Haskell; and as I’ve learned more type theory, I’ve begun to use it as a playground for type system research.

The goal is to allow pure functional programming that “feels imperative”, with a simple performance model (unboxed values by default, in-place updates, no laziness) and minimal runtime support (no GC, eventually no libc).

The latest compiler is nearly complete, but not yet usable for real programming. Still, you may like to keep an eye on its development.

[1]: https://github.com/evincarofautumn/kitten

---

carapace 83 days ago [-]

Long ago I found a copy of "System Design from Provably Correct Constructs" at the Seattle public library. I didn't realize it at the time but I now know that it is basically a presentation of Dr. Margaret Hamilton's Higher-Order Software ideas. In essence it's a thin AST that is only modified by operations that preserve certain kinds of correctness (i.e. type safety), with a tiny core of essential combinators that are combined (again, in "provably correct" ways) to form control-flow constructs. I was struck by the essential simplicity and spent time on and off trying to get a implementation working. (It never amounted to much but it DID get me my first job as a programmer!)

Eventually, I found Manfred von Thun's Joy language and realized that it was better than my thing and now I've implemented that in Python in Continuation-Passing Style. https://github.com/calroc/joypy

I think Joy is pretty amazing. It's a Functional Programming language that superficially resembles Forth, in that it's stack-based, but it's much more like a mathematical notation. https://en.wikipedia.org/wiki/Joy_(programming_language)

nickpsecurity 83 days ago [-]

It's called Universal Systems Language. One of the founders of software engineering also was a pioneer in high-assurance toolkits. A NASA engineer's review showed the tool to have serious usability and performance issues. However, she and her team should get credit for solving the hard problems with a tool that at least worked for some people. It's also written in itself.

http://htius.com

Edit: The book you mention is on Amazon for $6 now. Ill buy a copy for historical inspiration if its contents go into detail with examples of applying her method to at least toy problems.

carapace 83 days ago [-]

It's like it went into its own bubble universe. Cheers.

As for the book, I don't know if I can recommend it. I've only ever seen a copy one other time, to check if it mentions Hamilton (it does, in some end notes) and I can't say it lived up to my memories of the first exposure. I can't even say how much of it is actually original to J. Martin and how much is strictly Dr. Hamilton's.

---

leafo 82 days ago [-]

MoonScript? is designed to compile to Lua, and there are no good ways to run Lua in the browser right now. It's impossible to write a Lua -> JS transpiler while matching all the same functionality (coroutines), so the only option is to run the entire Lua vm in the browser (The MoonScript? online version uses this approach with emscripten).

In the future I'd like to be able to run MoonScript? in the browser, maybe web assembly is the answer.

Another option would be to have a JS target for the MoonScript? compiler, but there are some issues with different language features that would make code sharing difficult (1 indexed arrays, metatables, etc.)

I have no plans to give up moonscript. I haven't been actively developing it recently though, which I feel guilty about.

---

Although I am not the creator of it, I am a frequent contributor to Pyret [0], (I'm the error message czar, and prototyped the language support for tabular data).

Beyond that: Writing an interpreter is typically the first thing I do when I am trying to pick up a new language.

To anyone interested in learning how to design and implement a programming language, I highly recommend the 2015 offering of Brown's "Programming Languages" [1]. Implementing type inference was a revelation for me! The starter code is supplied in Pyret, but the material isn't language-dependent; the assignments can be implemented in any language.

[0] http://www.pyret.org/ [1] http://cs.brown.edu/courses/cs173/2015/assignments.html

DenisM? 82 days ago [-]

Type inference is exactly what I need for my new language! Thank you!

---

about a language called 'lionness' which is kind of like Swift+GPU shaders, apparently:

" The standard library (abbreviated: stdlib) contains basic functions for number manipulation, including: max/min, ceil, floor, trigonometry, etc. However, more trivial functions, such as to calculate prime numbers, are not considered relevant for the standard library. Source examples

The following Lioness code calculates factorials recursively:

func factorial(x) returns {

    if x > 1 {
        return x * factorial(x - 1)
    }
	
    return 1}

a = factorial(5) a = 120

The following Lioness code uses a do times loop:

a = 1 n = 10 do n times { a += a } a = 1024

More examples can be found here. Features

    Minimalistic, yet expressive, syntax
    All types are inferred
    5 basic operators: +, -, /, * and ^
        ^ means "to the power of", e.g. 2^10 would equal 1024
        all operators have a shorthand, e.g. += for +
    Numbers
        All numbers are floating point
    Booleans
        Can be evaluated from comparison
        Can be defined by literal: true or false
    Functions
        Supports parameters, returning and recursion
        Can be declared inside other functions
    Structs
        Can contain any type, including other structs
    Loops
        for
        while
        do times
        repeat while
        break
        continue
    if / else / else if statements"

---

nickpsecurity 3 hours ago [-]

"Same thing applies to NaCl? verifier. Bugs in verifier can cause problems. "

Not like with the other, though. You can statically verify NaCl? stuff because it was designed for that to be easy. If WebAssembly? doesn't do that, then it's a step down from NaCl? at least on this risk. That it matters should be obvious given all the research by the kind of CompSci? people that invented NaCl? on eliminating that risk from the TCB. It's part of a larger concept where you make the things generating the risky code untrusted with the trusted checkers so simple they can be mathematically verified. Here's an example from a top group on NaCl?:

http://www.cse.psu.edu/~gxt29/paper/rocksalt.pdf

I'm not worried about this too much as it will probably be some brilliant student's personal project in near future if it's not being researched already. A quick Google shows the Github has the full, C semantics with compiler (KCC) and a Javascript semantics at least has a prototype from 2015 of WebAssembly?.

https://github.com/kframework/wasm-semantics

reply

---

http://www.cse.psu.edu/~gxt29/paper/rocksalt.pdf

https://github.com/kframework/wasm-semantics

---

for list comprehensions, may want to evaluation the filter BEFORE the map, so that you can do things in the map which would cause an error if the filter isn't true

(i think this is how python does it; eg

[{1:2}[x] for x in [1,3] if x in {1:2}.keys()]
== [2]

---

https://github.com/karan/Projects

A list of practical projects that anyone can solve in any programming language

eg fizz buzz, alarm clock

similarly, https://projecteuler.net/ http://rosalind.info/problems/locations/

https://github.com/seaneshbaugh/rosetta-euler https://github.com/lunixbochs/project-euler

---