API's that Suck

January 2, 2010

Foundry – Types of Variables and Variable Types

Filed under: Foundry — Grauenwolf @ 9:30 pm

It seems I’ve gotten a bit ahead of myself. Why talk about passing variables to functions before you figure out how to define a variable.

One of the things that really sucks about .NET is that variables are nullable and mutable by default. While I have never seen any convincing evidence for getting rid of either, there is plenty of reasons to limit them as much as possible. So whatever is decided needs to tackle both aspects.

Between VB and C#, I much prefer VB’s syntax. It is easier to parse, with its leading keyword, and looks the same whether or not you are using type inference. But it still has flaws such as the totally unnecessary “As” keyword. Using “dim” versus “const” sounds good, so lets start there.

Define

Define variables are variables that can only be set once and not changed from there on out. Foundry doesn’t expect programmers distinguish between statically compiled, CLR-style constants and variables that are simply assign-once, that’s what compilers are for. Likewise, type is inferred from the expression.

<Define-Statement> := “Define” <Identifier> “=” <Expression>

Declare

Declare variables are variables whose value can be changed. They require a type, which can be made nullable using the ‘?’ operator. An initial value is required if the type is left off or the variable is not nullable.

<Declare-Statement> := “Declare” <Identifier> [<Type> [ “?” ]]  “=” <Expression>
<Declare-Statement> := “Declare” <Identifier> <Type> [ “=” <Expression> ]

At some point that should be some escape analysis to make it possible to leave of the expression for non-nullable variables, but it will have to wait.

String Literals

There is another post on this one.

Date/Time Literals

Unless someone else has a reason otherwise, I’m going to adopt VB’s style of date literals for both dates and times. T-SQL just uses the string literal syntax, but that means you don’t get type inference.

<Time-Literal> := #hh:MM:ss.fffff#
<Date-Literal> := #yyyy-mm-dd#
<DateTime-Literal> := #yyyy-mm-ddThh:MM:ss.fffff#
<DateTimeOffset-Literal> := #yyyy-mm-ddThh:MM:ss.fffffZ# | #yyyy-mm-ddThh:MM:ss.fffff [+/-] hh:mm#

Numeric Literals

If the number contains a decimal place, then it is treated as Decimal. Integers default to Int32. If they don’t fit, they will be automatically treated as an Int64. If they don’t fit within that either, a Decimal is used.

Advertisements

Foundry: What kind of string literals should be used by default?

Filed under: Foundry — Grauenwolf @ 9:21 pm

There are a lot of options for string literals, but which to choose as the default? I’m inclined to choose verbatim strings because I’m primarily a VB and T-SQL programmer, but the other forms do have merits.

Verbatim Strings

The easiest is the one used by CSV, VB, and SQL, where in there is no escape sequences except for quotes. C# uses this as a secondary form, accessed using @" instead of the usual ".

Escaped Strings

Escaped strings are what languages like Java and C# use by default.  They use the backslash to start a escape sequence. This makes strings that actually use backslashes like file paths annoying.

Interpolated Strings

String interpolation, where in variables and expressions can be inlined right into the string literal. Under the covers this would be implemented using the String.Format function call. This could be combined with either of the two above formats.

Why not all of the above?

C# already offers two of the three by tacking an extra symbol to the front of a string to indicate it should be handled differently. But which to choose as the default?

Foundry – Unattached Functions

Filed under: Foundry — Grauenwolf @ 1:19 am

An unattached functions is a function that isn’t tied to any specific class or module. It just floats around in the global namespace. In addition to a executable’s entry point, this will be used primarily for scripting.

Action

An action is a function that doesn’t have a return value.  It has both a inline and a block form. The block terminator is very forgiving, allowing one to choose between braces or the “end” keyword. If you choose to use end, then you can optionally specify either the word “Action” or the name of the function.

<Action-Block> := <Action-Header> [ “{“ ] <EOL> <Imperative-Block> <Action-Footer>
<Action-Header> := “Action” <Identifier> <Params>
<Action-Footer> := “End” | “End Action” | End <Identifier> | “}”

The inline variant of this is detonated by  either the keyword “Then” or a colon. It allows for a single statement followed by and end-of-line token.

<Action-Inline> := <Action-Header> <Inline-Marker> <Statement> <EOL>
<Inline-Marker> := “Then” | “:”

Func

A Func is a function that has a return value.

<Func-Block> := <Func-Header> <Type> [ “{“ ] <EOL> <Imperative-Block> <Func-Footer>
<Func-Header> := “Func” <Identifier> <Params>
<Func-Footer> := “End” | “End Func” | End <Identifier> | “}”

The inline version of the Func doesn’t require a type. If not provided, it is inferred from the expression that follows.

<Func-Inline> := <Func-Header> [<Type>] <Inline-Marker> <Expression> <EOL>

Main

Main is a function that serves as the entry point for an application. By default it has an implied parameter called “args String[]” and an implied return type Int32.

<Main-Block> := “Main” [ “{“ ] <EOL> <Imperative-Block> <Main-Footer>
<Main-Footer> := “End” | “End Main” | “}”

Parameters

Obviously parameters are going to be encapsulated by parens. It is a tried and true method of handling such matters, though what goes inside the parens can vary greatly from language to language. More on this another day, its late and my brain is fuzzy.

January 1, 2010

Foundry – Block Terminators II

Filed under: Foundry — Grauenwolf @ 8:03 pm

Ok, so here are our candidates from round 1.

Candidate A

Candidate B

Candidate C

Candidate D

  1. Program Test1 {
  2.     References {
  3.         mscorlib
  4.     }
  5. }
  6.  
  7. Main {
  8.     Print "Hello World"
  9. }

  1. Program Test1
  2.     References
  3.         mscorlib
  4.     }
  5. }
  6.  
  7. Main
  8.     Print "Hello World"
  9. }

  1. Program Test1
  2.     References
  3.         mscorlib
  4.     End References
  5. End Program
  6.  
  7. Main
  8.     Print "Hello World"
  9. End Main

  1. Program Test1
  2.     References
  3.         mscorlib
  4.     End
  5. End
  6.  
  7. Main
  8.     Print "Hello World"
  9. End

Candidate A

A is better than B because…

  • There is a clear syntax for arbitrary blocks.
  • It doesn’t have unmatched braces.

A is better than C because…

  • It takes less characters to express the same concept.
  • There is a clear syntax for arbitrary blocks.

A is better than D because…

  • It takes less characters to express the same concept.
  • There is a clear syntax for arbitrary blocks.

Candidate B

B is better than A because…

  • It takes less characters to express the same concept.
  • It takes less tokens to express the same concept.

B is better than C because…

  • It takes less characters to express the same concept.

B is better than D because…

  • It takes less characters to express the same concept.
  • It takes less tokens to express the same concept.

Candidate C

C is better than A because…

  • Easier for users to know which block is being closed.
  • Easier for the compiler to give meaningful feedback.
  • Keywords are easier to spot than semi-colons.

C is better than B because…

  • Easier for users to know which block is being closed.
  • Easier for the compiler to give meaningful feedback.
  • Keywords are easier to spot than semi-colons.
  • It doesn’t have unmatched braces.

C is better than D because…

  • Easier for users to know which block is being closed.
  • Easier for the compiler to give meaningful feedback.

Candidate D

D is better than A because…

  • It takes less tokens to express the same concept.
  • Keywords are easier to spot than semi-colons.

D is better than B because…

  • Keywords are easier to spot than semi-colons.
  • It doesn’t have unmatched braces.

D is better than C because…

  • It takes less tokens to express the same concept.
  • It takes less characters to express the same concept.

Conclusion… not yet

It is too soon to pick a winner, though my personal bias tends towards one. I’m looking for some thoughts from others before I commit myself.

Foundry – Block Terminators I

Filed under: Foundry — Grauenwolf @ 6:50 pm

First an introduction. Foundry is meant to be a general purpose programming language that targets the CLR. I call it Foundry because there will be a heavy emphasis on making intelligent data objects. Building data objects tends to be very tedious. I especially when you start looking at wiring in update events for WPF, creating immutable variants of each class, tagging everything for serialization, etc.

Block Terminators

The construction of blocks is vital for most programming languages.  Popular options include keywords, braces, and whitespace. In order to test the options, I am looking at a hello world program. Using three block we see the program name, the list of assemblies that the program references, and the main function.

Whitespace 

  1. Program Test1
  2.     References
  3.         mscorlib
  4. Main
  5.     Print “Hello World”

I’m discarding this option because every time I try to copy and paste it the white spaces gets messed up.

Braces and Parens

There are three commonly used format for braces and parens.

Variant 1 – Suffix

  1. Program Test1 {
  2.     References {
  3.         mscorlib
  4.     }
  5. }
  6.  
  7. Main {
  8.     Print “Hello World”
  9. }

Variant 1 is in the running for now.

Variant 2 – Suffix on new line

  1. Program Test1
  2. {
  3.     References
  4.     {
  5.         mscorlib
  6.     }
  7. }
  8.  
  9. Main
  10. {
  11.     Print “Hello World”
  12. }

Burning two lines for each block header just seems stupid to me, so this one it out.

Variant 3 – Prefix

  1. {Program Test1
  2.     {References
  3.         mscorlib
  4.     }
  5. }
  6.  
  7. {Main
  8.     Print “Hello World”
  9. }

Placing the braces before the the block keyword makes it obvious that they pretty redundant. So how about a fourth variant instead.

Variant 4 – Closing only

  1. Program Test1
  2.     References
  3.         mscorlib
  4.     }
  5. }
  6.  
  7. Main
  8.     Print “Hello World”
  9. }

Very succinct, though perhaps a different closing character is in order. Definitely in the running.

Keywords

Variant 1 – End keyword with block identifier

  1. Program Test1
  2.     References
  3.         mscorlib
  4.     End References
  5. End Program
  6.  
  7. Main
  8.     Print “Hello World”
  9. End Main

This is redundant, but it does allow for a smarter compiler. If you see “end program” before “end references”, then you can tell the user what’s going on. Or you could even implicitly end the previous block. So this one is in the running.

Variant 2 – End keyword

  1. Program Test1
  2.     References
  3.         mscorlib
  4.     End
  5. End
  6.  
  7. Main
  8.     Print “Hello World”
  9. End

This isn’t quite as clear as the other one, but it is nice and terse.

Blog at WordPress.com.