Live data from Hacker News

Main is usually a function. So then when is it not? (2015)

jroweboy.github.io

41–50 of 59 posts

Re: Main is usually a function. So then when is it not? (2015)

#41
post #25
post #18

Earlier quoted context omitted.

> There's something more constricting about there being one function to bootstrap everything than there is about one file. As a compiler author, there are a bunch of nasty surprises to this approach. If you execute a file line-by-line, then functions only exist once you "reach" them. If you write: def a(): b() a() def b(): ... ...then a() needs to crash when first called, because b() hasn't been declared yet. So your…

> ...then a() needs to crash when first called, because b() hasn't been declared yet. Why would it “need to” crash? If it is easier to implement to not crash and the developer intention is clear why would you define your new programing language such that it “needs to crash” in this situation? It is as if you go to your garden to pick tomatoes, but you trip over a rake you intentionally put in your way and then as you…

> Why would it “need to” crash? If it is easier to implement to not crash and the developer intention is clear why would you define your new programing language such that it “needs to crash” in this situation?

Well, let me come up with another example:

    def a(x=SIZE): ...
    a()
    let SIZE = 16*1024
When we call a(), we need the value of SIZE to provide the a default value for x. But SIZE isn't computed yet. We could try to "hoist" SIZE, but normally that just means we have:

    let SIZE = undefined
    def a(x=SIZE): ...
    a()
    SIZE = 16*1024
And sure, you could invent a rule to "fix" this case, too. (It depends on how you implement default arguments efficiently.) But next week, you'll encounter another headache, and another. I've literally been through this a couple of times working on LISP compilers. "Executional" semantics are common in custom Lisp dialects, and it's a huge amount of work to get them right.

The price you end up paying is lower program performance and higher compiler complexity. Oh, and importantly, you normally wind up with slower load times. A compiled program is "ready to run", and can be loaded efficiently using mmap() and maybe some linking. But a program where you "execute" the top level needs to run all those top-level definitions on each load. So then you're like, "I know! I'll write a heap dumper/undumper", aka "unexec". Which will fix this problem but cause 5 more.

And so it goes. This is one of those ideas that seems clever but leads to bitter regrets, at least in high performance languages.

Re: Main is usually a function. So then when is it not? (2015)

#42

Earlier quoted context omitted.

Hey just on a completely off-topic thing, I like your style. But I typed the name of your website into the URL bar, and even stupid Firefox just hung trying to load or trying to redirect from what it thinks should be the default https version. Had to specify http:// to load it. The browsers are making it almost impossible these days to just go to a plain website. half the time they loop themselves into a frenzy and c…

> even stupid Firefox just hung trying to load or trying to redirect from what it thinks should be the default https version Cannot reproduce. The only problem(s) I'm seeing are related to operator error; nothing to do with browsers "loop[ing] themselves into a frenzy". The server at www.randomhacks.net works, but the server at randomhacks.net, on the other hand (and which is not the same as www.randomhacks.net), is…

> The server at www.randomhacks.net works, but the server at randomhacks.net, on the other hand (and which is not the same as www.randomhacks.net), is for whatever reason failing to respond to the HTTP request. Reasonable guess: it's not a Web server.

Yes, the entire setup is ancient. The www site is a static using CloudFlare, which (IIRC) needed a CNAME at the time, and CNAMEs did not work nicely with "bare" domains. The bare domain pointed to an actual server which did stuff, including serving a redirect on port 443. But that server is gone now.

I could fix this but it's way down the list after several major home projects. Besides, I come from an era where it was assumed that the www host was a dedicated machine. ;-)

Re: Main is usually a function. So then when is it not? (2015)

#43
post #30
post #18

Earlier quoted context omitted.

> There's something more constricting about there being one function to bootstrap everything than there is about one file. As a compiler author, there are a bunch of nasty surprises to this approach. If you execute a file line-by-line, then functions only exist once you "reach" them. If you write: def a(): b() a() def b(): ... ...then a() needs to crash when first called, because b() hasn't been declared yet. So your…

how about before anything is executed, add a parse step that reads the whole file, looks for function definitions, and then goes back to the start to execute?

What counts as a function definition?

  def a(): b()
  a()
  import random
  with open("max", "r") as f:
    m = int(f.read())
    b = (lambda: "foo") if int(input("Pick a number: ")) % m > random.randint(0, m) else None

Re: Main is usually a function. So then when is it not? (2015)

#44
post #3

Back when compiler warnings possibly cost extra processing time to generate, it was possible to make gcc compile the craziest things. After much experimentation, it turned out that the smallest program that would compile and run was only 5 bytes long: main;

Welp that's a nerd snipe if I ever had one. Will report back once my bruteforce hack finishes crunching away.

Re: Main is usually a function. So then when is it not? (2015)

#45
post #20

This is fun. On a broader note though, entry point main-type functions have always bothered me. Maybe because I grew up as a simple script kiddie with BASIC and Bash and PHP. I like code that starts executing from the first line and then runs whatever functions it wants to run. I realize that's just an abstraction of main() but it's a pleasant one for me. There's something more constricting about there being one func…

> There's something more constricting about there being one function to bootstrap everything than there is about one file. As someone who basically started coding with C I feel the other way around, unsurprisingly. Even in scripting languages when I write something non trivial I tend to encapsulate everything in functions and then have a `main()` call at the bottom of the file. I think it's one of the things python g…

> (Although the actual syntax of `if __name__ == "__main__":` is IMO utter trash and it amuses me that a language so obsessed with getting rid of symbols and looking like pseudocode decided that such cumbersome, obtuse and ugly looking boilerplate was just fine.)

This reminds me of when I tried learning Ruby. The tutorial I read started by talking about how elegant and beautiful Ruby could be, and how easy it is to read and understand Ruby at first glance, even if you’re new to it. Then they explained that the toString method in Ruby is called `.to_s()` and that lambda arguments were surrounded by pipe characters and I was like “wat”.

Re: Main is usually a function. So then when is it not? (2015)

#46
post #20

This is fun. On a broader note though, entry point main-type functions have always bothered me. Maybe because I grew up as a simple script kiddie with BASIC and Bash and PHP. I like code that starts executing from the first line and then runs whatever functions it wants to run. I realize that's just an abstraction of main() but it's a pleasant one for me. There's something more constricting about there being one func…

> There's something more constricting about there being one function to bootstrap everything than there is about one file. As someone who basically started coding with C I feel the other way around, unsurprisingly. Even in scripting languages when I write something non trivial I tend to encapsulate everything in functions and then have a `main()` call at the bottom of the file. I think it's one of the things python g…

Python is quick and dirty and always has been. The language designers have regularly papered over design flaws using hacks and magic syntax.

Which is acceptable. Python is a valuable tool I use on a daily basis. But I find it annoying when Python programmers are snooty about "Pythonic" code.

Re: Main is usually a function. So then when is it not? (2015)

#47
post #18

This is fun. On a broader note though, entry point main-type functions have always bothered me. Maybe because I grew up as a simple script kiddie with BASIC and Bash and PHP. I like code that starts executing from the first line and then runs whatever functions it wants to run. I realize that's just an abstraction of main() but it's a pleasant one for me. There's something more constricting about there being one func…

> There's something more constricting about there being one function to bootstrap everything than there is about one file. As a compiler author, there are a bunch of nasty surprises to this approach. If you execute a file line-by-line, then functions only exist once you "reach" them. If you write: def a(): b() a() def b(): ... ...then a() needs to crash when first called, because b() hasn't been declared yet. So your…

Javascript solves this with function hoisting. In simplified terms you do two compiler passes, once for global symbols and once for linear execution.

After all nothing stops you from writing in your language definition that defining a function anywhere in the file is the same as defining it in the beginning, and then you can treat it as if the entire file was in a main function, except for functions and the declaration of global variables.

Re: Main is usually a function. So then when is it not? (2015)

#48
post #41
post #25

Earlier quoted context omitted.

> ...then a() needs to crash when first called, because b() hasn't been declared yet. Why would it “need to” crash? If it is easier to implement to not crash and the developer intention is clear why would you define your new programing language such that it “needs to crash” in this situation? It is as if you go to your garden to pick tomatoes, but you trip over a rake you intentionally put in your way and then as you…

> Why would it “need to” crash? If it is easier to implement to not crash and the developer intention is clear why would you define your new programing language such that it “needs to crash” in this situation? Well, let me come up with another example: def a(x=SIZE): ... a() let SIZE = 16*1024 When we call a(), we need the value of SIZE to provide the a default value for x. But SIZE isn't computed yet. We could try t…

Thank you for the example.

> And sure, you could invent a rule to "fix" this case, too.

I would just do the simple thing. If X is not already defined when it is used in the function signature I would just give a compile time error. Easy to implement for the compiler author, easy for the developer to understand and rectify.

> But next week, you'll encounter another headache, and another.

I believe you. I guess it is one of those things one has to see for themselves to really appreciate.

Re: Main is usually a function. So then when is it not? (2015)

#49
post #20

Earlier quoted context omitted.

> There's something more constricting about there being one function to bootstrap everything than there is about one file. As someone who basically started coding with C I feel the other way around, unsurprisingly. Even in scripting languages when I write something non trivial I tend to encapsulate everything in functions and then have a `main()` call at the bottom of the file. I think it's one of the things python g…

Python is quick and dirty and always has been. The language designers have regularly papered over design flaws using hacks and magic syntax. Which is acceptable. Python is a valuable tool I use on a daily basis. But I find it annoying when Python programmers are snooty about "Pythonic" code.

The thesis I've heard (and agree with) is that Python is a good everything language. For specialization there is always a better tool (although maybe more complex to get started).

Re: Main is usually a function. So then when is it not? (2015)

#50
Well, if you really want to confound things you could write your own __start which is typically the entry point called by the kernel, which in turn calls `main()`.

But actually that's just by convention: C (and C++) programs drop `__start` into the binary and then tell the linker to mark the binary (mostly an ELF file these days, thank goodness) to indicate that the entry point is the symbol `__start`. There can be different versions depending on how many arguments to `main()` are requested, or it can simply pass all three and let the function body ignore the unwanted ones.

If you really want to confuse the TA, write the following program:

    #include 

    void foo();

    int main() {
      printf ("I'm in main\n");
      foo();
      printf ("I'm still in main\n");
    }

    void foo() {
      printf ("I'm in foo!\n");
    }
Then tell the linker to mark `foo` as your entry point. You could do this from the command line or even a custom linker script.

Of course depending on what your OS needs from `__start` you may have to do some extra setup, sorry. But this might work on Linux.

I've actually been thinking of modifying gcc's `__start` to pass the arguments and env vars as a span (well, the function __start calls that calls `main()`.)

Post reply on HN