|
|
Subscribe / Log in / New account

An introduction to the Julia language, part 1

August 28, 2018

This article was contributed by Lee Phillips

Julia is a young computer language aimed at serving the needs of scientists, engineers, and other practitioners of numerically intensive programming. It was first publicly released in 2012. After an intense period of language development, version 1.0 was released on August 8. The 1.0 release promises years of language stability; users can be confident that developments in the 1.x series will not break their code. This is the first part of a two-part article introducing the world of Julia. This part will introduce enough of the language syntax and constructs to allow you to begin to write simple programs. The following installment will acquaint you with the additional pieces needed to create real projects, and to make use of Julia's ecosystem.

Goals and history

The Julia project has ambitious goals. It wants the language to perform about as well as Fortran or C when running numerical algorithms, while remaining as pleasant to program in as Python. I believe the project has met these goals and is poised to see increasing adoption by numerical researchers, especially now that an official, stable release is available.

The Julia project maintains a micro-benchmark page that compares its numerical performance against both statically compiled languages (C, Fortran) and dynamically typed languages (R, Python). While it's certainly possible to argue about the relevance and fairness of particular benchmarks, the data overall supports the Julia team's contention that Julia has generally achieved parity with Fortran and C; the benchmark source code is available.

Julia began as research in computer science at MIT; its creators are Alan Edelman, Stefan Karpinski, Jeff Bezanson, and Viral Shah. These four remain active developers of the language. They, along with Keno Fischer, co-founder and CTO of Julia Computing, were kind enough to share their thoughts with us about the language. I'll be drawing on their comments later on; for now, let's get a taste of what Julia code looks like.

Getting started

To explore Julia initially, start up its standard read-eval-print loop (REPL) by typing julia at the terminal, assuming that you have installed it. You will then be able to interact with what will seem to be an interpreted language — but, behind the scenes, those commands are being compiled by a just-in-time (JIT) compiler that uses the LLVM compiler framework. This allows Julia to be interactive, while turning the code into fast, native machine instructions. However, the JIT compiler passes sometimes introduce noticeable delays at the REPL, especially when using a function for the first time.

To run a Julia program non-interactively, execute a command like:

    $ julia script.jl <args>

Julia has all the usual data structures: numbers of various types (including complex and rational numbers), multidimensional arrays, dictionaries, strings, and characters. Functions are first-class: they can be passed as arguments to other functions, can be members of arrays, and so on.

Julia embraces Unicode. Strings, which are enclosed in double quotes, are arrays of Unicode characters, which are enclosed in single quotes. The "*" operator is used for string and character concatenation. Thus 'a' and 'β' are characters, and 'aβ' is a syntax error. "a" and "β" are strings, as are "aβ", 'a' * 'β', and "a" * "β" — all evaluate to the same string.

Variable and function names can contain non-ASCII characters. This, along with Julia's clever syntax that understands numbers prepended to variables to mean multiplication, goes a long way to allowing the numerical scientist to write code that more closely resembles the compact mathematical notation of the equations that usually lie behind it.

    julia> ε₁ = 0.01
    0.01

    julia> ε₂ = 0.02
    0.02

    julia> 2ε₁ + 3ε₂
    0.08

And where does Julia come down on the age-old debate of what do about 1/2? In Fortran and Python 2, this will get you 0, since 1 and 2 are integers, and the result is rounded down to the integer 0. This was deemed inconsistent, and confusing to some, so it was changed in Python 3 to return 0.5 — which is what you get in Julia, too.

While we're on the subject of fractions, Julia can handle rational numbers, with a special syntax: 3//5 + 2//3 returns 19//15, while 3/5 + 2/3 gets you the floating-point answer 1.2666666666666666. Internally, Julia thinks of a rational number in its reduced form, so the expression 6//8 == 3//4 returns true, and numerator(6//8) returns 3.

Arrays

Arrays are enclosed in square brackets and indexed with an iterator that can contain a step value:

    julia> a = [1, 2, 3, 4, 5, 6]
    6-element Array{Int64,1}:
     1
     2
     3
     4
     5
     6

    julia> a[1:2:end]
    3-element Array{Int64,1}:          
     1
     3
     5

As you can see, indexing starts at one, and the useful end index means the obvious thing. When you define a variable in the REPL, Julia replies with the type and value of the assigned data; you can suppress this output by ending your input line with a semicolon.

Since arrays are such a vital part of numerical computation, and Julia makes them easy to work with, we'll spend a bit more time with them than the other data structures.

To illustrate the syntax, we can start with a couple of 2D arrays, defined at the REPL:

    julia> a = [1 2 3; 4 5 6]
    2×3 Array{Int64,2}:
     1  2  3
     4  5  6

    julia> z = [-1 -2 -3; -4 -5 -6];

Indexing is as expected:

    julia> a[1, 2]
    2

You can glue arrays together horizontally:

    julia> [a z]
    2×6 Array{Int64,2}:
     1  2  3  -1  -2  -3
     4  5  6  -4  -5  -6

And vertically:

    julia> [a; z]
    4×3 Array{Int64,2}:
      1   2   3
      4   5   6
     -1  -2  -3
     -4  -5  -6

Julia has all the usual operators for handling arrays, and linear algebra functions that work with matrices (2D arrays). The linear algebra functions are part of Julia's standard library, but need to be imported with a command like "using LinearAlgebra", which is a detail omitted from the current documentation. The functions include such things as determinants, matrix inverses, eigenvalues and eigenvectors, many kinds of matrix factorizations, etc. Julia has not reinvented the wheel here, but wisely uses the LAPACK Fortran library of battle-tested linear algebra routines.

The extension of arithmetic operators to arrays is usually intuitive:

    julia> a + z
    2×3 Array{Int64,2}:
     0  0  0
     0  0  0

And the numerical prepending syntax works with arrays, too:

    julia> 3a + 4z
    2×3 Array{Int64,2}:
     -1  -2  -3
     -4  -5  -6

Putting a multiplication operator between two matrices gets you matrix multiplication:

    julia> a * transpose(a)
    2×2 Array{Int64,2}:
     14  32
     32  77

You can "broadcast" numbers to cover all the elements in an array by prepending the usual arithmetic operators with a dot:

    julia> 1 .+ a
    2×3 Array{Int64,2}:
     2  3  4
     5  6  7

Note that the language only actually requires the dot for some operators, but not for others, such as "*" and "/". The reasons for this are arcane, and it probably makes sense to be consistent and use the dot whenever you intend broadcasting. Note also that the current version of the official documentation is incorrect in claiming that you may omit the dot from "+" and "-"; in fact, this now gives an error.

You can use the dot notation to turn any function into one that operates on each element of an array:

    julia> round.(sin.([0, π/2, π, 3π/2, 2π]))
    5-element Array{Float64,1}:
      0.0
      1.0
      0.0
     -1.0
     -0.0

The example above illustrates chaining two dotted functions together. The Julia compiler turns expressions like this into "fused" operations: instead of applying each function in turn to create a new array that is passed to the next function, the compiler combines the functions into a single compound function that is applied once over the array, creating a significant optimization.

You can use this dot notation with any function, including your own, to turn it into a version that operates element-wise over arrays.

Dictionaries (associative arrays) can be defined with several syntaxes. Here's one:

    julia> d1 = Dict("A"=>1, "B"=>2)
    Dict{String,Int64} with 2 entries:
      "B" => 2
      "A" => 1

You may have noticed that the code snippets so far have not included any type declarations. Every value in Julia has a type, but the compiler will infer types if they are not specified. It is generally not necessary to declare types for performance, but type declarations sometimes serve other purposes, that we'll return to later. Julia has a deep and sophisticated type system, including user-defined types and C-like structs. Types can have behaviors associated with them, and can inherit behaviors from other types. The best thing about Julia's type system is that you can ignore it entirely, use just a few pieces of it, or spend weeks studying its design.

Control flow

Julia code is organized in blocks, which can indicate control flow, function definitions, and other code units. Blocks are terminated with the end keyword, and indentation is not significant. Statements are separated either with newlines or semicolons.

Julia has the typical control flow constructs; here is a while block:

    julia> i = 1;

    julia> while i < 5
	       print(i)
	       global i = i + 1
	   end
    1234

Notice the global keyword. Most blocks in Julia introduce a local scope for variables; without this keyword here, we would get an error about an undefined variable.

Julia has the usual if statements and for loops that use the same iterators that we introduced above for array indexing. We can also iterate over collections:

    julia> for i ∈ ['a', 'b', 'c']
	       println(i)
	   end
    a
    b
    c

In place of the fancy math symbol in this for loop, we can use "=" or "in". If you want to use the math symbol but have no convenient way to type it, the REPL will help you: type "\in" and the TAB key, and the symbol appears; you can type many LaTeX expressions into the REPL in this way.

Development of Julia

The language is developed on GitHub, with over 700 contributors. The Julia team mentioned in their email to us that the decision to use GitHub has been particularly good for Julia, as it streamlined the process for many of their contributors, who are scientists or domain experts in various fields, rather than professional software developers.

The creators of Julia have published [PDF] a detailed “mission statement” for the language, describing their aims and motivations. A key issue that they wanted their language to solve is what they called the "two-language problem." This situation is familiar to anyone who has used Python or another dynamic language on a demanding numerical problem. To get good performance, you will wind up rewriting the numerically intensive parts of the program in C or Fortran, dealing with the interface between the two languages, and may still be disappointed in the overhead presented by calling the foreign routines from your original code.

For Python, NumPy and SciPy wrap many numerical routines, written in Fortran or C, for efficient use from that language, but you can only take advantage of this if your calculation fits the pattern of an available routine; in more general cases, where you will have to write a loop over your data, you are stuck with Python's native performance, which is orders of magnitude slower. If you switch to an alternative, faster implementation of Python, such as PyPy, the numerical libraries may not be compatible; NumPy became available for PyPy only within about the past year.

Julia solves the two-language problem by being as expressive and simple to program in as a dynamic scripting language, while having the native performance of a static, compiled language. There is no need to write numerical libraries in a second language, but C or Fortran library routines can be called using a facility that Julia has built-in. Other languages, such as Python or R, can also interoperate easily with Julia using external packages.

Documentation

There are many resources to turn to to learn the language. There is an extensive and detailed manual at Julia headquarters, and this may be a good place to start. However, although the first few chapters provide a gentle introduction, the material soon becomes dense and, at times, hard to follow, with references to concepts that are not explained until later chapters. Fortunately, there is a "learning" link at the top of the Julia home page, which takes you to a long list of videos, tutorials, books, articles, and classes both about Julia and that use Julia in teaching subjects such a numerical analysis. There is also a fairly good cheat-sheet [PDF], which was just updated for v. 1.0.

If you're coming from Python, this list of noteworthy differences between Python and Julia syntax will probably be useful.

Some of the linked tutorials are in the form of Jupyter notebooks — indeed, the name "Jupyter" is formed from "Julia", "Python", and "R", which are the three original languages supported by the interface. The Julia kernel for Jupyter was recently upgraded to support v. 1.0. Judicious sampling of a variety of documentation sources, combined with liberal experimentation, may be the best way of learning the language. Jupyter makes this experimentation more inviting for those who enjoy the web-based interface, but the REPL that comes with Julia helps a great deal in this regard by providing, for instance, TAB completion and an extensive help system invoked by simply pressing the "?" key.

Stay tuned

The next installment in this two-part series will explain how Julia is organized around the concept of "multiple dispatch". You will learn how to create functions and make elementary use of Julia's type system. We'll see how to install packages and use modules, and how to make graphs. Finally, Part 2 will briefly survey the important topics of macros and distributed computing.

Index entries for this article
GuestArticlesPhillips, Lee


to post comments

An introduction to the Julia language, part 1

Posted Aug 29, 2018 0:24 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link] (12 responses)

Love Julia. But I hate the one-based indexes.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 0:39 UTC (Wed) by leephillips (subscriber, #100450) [Link] (11 responses)

You can change that:
https://julialang.org/blog/2017/04/offset-arrays

(I'm used to it from Fortran (where you can also change it).)

An introduction to the Julia language, part 1

Posted Aug 29, 2018 2:07 UTC (Wed) by k8to (guest, #15413) [Link] (3 responses)

Pascal revisited.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 10:38 UTC (Wed) by eru (subscriber, #2753) [Link] (2 responses)

Pascal revisited.

Not really. In Pascal, you always define the upper and lower index of an array in a readable way, like

var a: array [0 .. 9] of real;
so the Pascal array type is not really 0-based or 1-based.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 13:29 UTC (Wed) by jem (subscriber, #24231) [Link]

True, but the convention in Pascal is that indices are 1-based. In addition, Pascal as defined by Wirth and also Standard Pascal (ISO 7185) don't support constant expressions, so you can't write something like this:

const TABLESIZE = 10;
var table: array[0..TABLESIZE-1];

Strings in Pascal are implicitly of type

packed array [1..N] of char
i.e. they are 1-based.

It is perhaps worth mentioning that array declarations in Oberon (a later programming language by Wirth) only include the size of the array, and array indices start with 0.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 21:34 UTC (Wed) by k8to (guest, #15413) [Link]

Yes, and you can customize in Julia as well. Seems to be parallel to me.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 2:10 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link]

It's better to have a single style across all of the code and by now lots of Julia libraries assume the 1-based indexing :(

An introduction to the Julia language, part 1

Posted Aug 29, 2018 8:39 UTC (Wed) by renox (guest, #23785) [Link] (5 responses)

Default matters! Libraries aren't good enough: I'm quite sure that by now there are a lot of Julia's code which will break if the array doesn't start at 1..
IMHO this is a "near fatal" flaw for Julia as a general purpose language, they should have copied Ada which allow any base index without problem..

PS: I've used Lua which is 1-indexed and now I hate 1-indexing too.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 9:15 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link] (4 responses)

Julia is not really a general-purpose language. You'd be stupid to write a website in it (unless it's a simple front-end for calculations).

It excels at math-heavy tasks, though.

An introduction to the Julia language, part 1

Posted Sep 2, 2018 2:59 UTC (Sun) by droundy (subscriber, #4559) [Link] (3 responses)

This seems like the major flaw in the idea that Julia solves the two language problem. If it's not a general purpose language then it's always going to be a second language for anyone with more than the most basic needs.

An introduction to the Julia language, part 1

Posted Sep 2, 2018 8:51 UTC (Sun) by Cyberax (✭ supporter ✭, #52523) [Link] (2 responses)

The "two language problem" here is for a very particular case of scientific code.

If you're using Python then you often have to use C/C++ to get enough performance because Python itself is too slow for naïve looped calculations.

An introduction to the Julia language, part 1

Posted Sep 3, 2018 12:14 UTC (Mon) by anselm (subscriber, #2796) [Link] (1 responses)

This is why many people in science these days use SciPy and NumPy, which essentially push many such calculations into C extensions and keep the Python code reasonably high-level and fast.

An introduction to the Julia language, part 1

Posted Sep 3, 2018 15:31 UTC (Mon) by leephillips (subscriber, #100450) [Link]

Yes, if your calculation is such that you can take advantage of these libraries, you will get the performance of C or Fortran, with, for many routines, automatic parallelization. But, as I said in the article, "you can only take advantage of this if your calculation fits the pattern of an available routine". What Julia offers is fast performance not only for standard manipulations, such as matrix multiplication, but for calculations that do not fit one of these molds, for which you would need to write loops over arrays or other data structures.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 4:14 UTC (Wed) by rsidd (subscriber, #2582) [Link] (50 responses)

I've used Julia for one major project, it really is the best language I have ever used -- as readable as python, as fast as C. The 1-indexing is not a big deal after the first couple of days and makes more sense to someone who does pencil-and-paper mathematics.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 12:24 UTC (Wed) by ibukanov (subscriber, #3942) [Link] (1 responses)

I second this observation about 1-indexing. I was doing a project using Numpy/Panda in Python with heavy math. It turned out translating formulas into code was much less intuitive with 0-based indexes despite my 25 programming background in languages using those. It is really that numerical programming and coding for GUI/databases/system services are very different things.

An introduction to the Julia language, part 1

Posted Sep 12, 2018 0:39 UTC (Wed) by ghane (guest, #1805) [Link]

To quote Donald Knuth: https://xkcd.com/163/

An introduction to the Julia language, part 1

Posted Aug 29, 2018 16:26 UTC (Wed) by danielpf (guest, #4723) [Link] (37 responses)

The 1-based indexing has been used in mathematics for ages because it is the way people count since prehistoric times.
Indeed almost everybody count sheeps, stones or people starting with 1, not 0.

The 0-based indexing was only thought a clever idea because then you can avoid "wasting" a memory word, or you can spare
an addition each time you want to find the memory location corresponding to an index.

Nowadays the energy cost and time needed for an supplementary addition are negligible with respect to one word
memory access, so this "optimisation" is no longer important. John Gustafson quotes 200 pJ and 1 nsec for a 64 bit addition,
and 12000 pJ and 70 nsec for reading 64 bits from DRAM.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 19:01 UTC (Wed) by rweikusat2 (subscriber, #117920) [Link] (24 responses)

"Prehistoric" means "we know nothing about it save what can be deduced/ inferred from artefacts because there are no written records dating back to this time". If you knew how people had counted in prehistoric times, they thus wouldn't have been prehistoric.
That's a contradictio in adiecto.

Likewise, your conjecture about "0-based indices" is wrong: C inherited this from B and in B, a[b] referred to the memory cell whose address was a + b (the B memory model being an array of cells address via their offest from the start of the array). And the meaning is exactly the same in C. a[0] is the array element whose distance from the start of the array is 0.

People also made arguments about this in the past:

https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08x...

The "And the moral of the story is that we had better regard —after all those centuries!— zero as a most natural number." refers to the fact that Roman numerals didn't have a notion of 0. This was an innovation of the nowadays common arabic numerals.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 20:52 UTC (Wed) by danielpf (guest, #4723) [Link] (22 responses)

> "Prehistoric" means "we know nothing about it save what can be deduced/ inferred from artefacts because there are no written
> records dating back to this time". If you knew how people had counted in prehistoric times, they thus wouldn't have been
> prehistoric.

Prehistoric practices have been documented, among others, by observing still in the 20th century populations that were ignoring the modern world. The frequent practice is to make a stroke for each item, so the *first* item gets a 1. Roman numerals I, II, III just illustrate this age old practice. Still today it is thus difficult for normal people to unlearn that and mark 0 for the first item.

And scientists are like normal people, they mostly don't care about the assembly language level elegance that Prof. Dijkstra was promoting. They just want to count and not index the memory location (first = 1, second = 2, etc.). As explained before the overhead for 1-indexing array is negligible nowadays, what is more important for a language dedicated to scientific computing like Julia is to ease computing with higher level mathematical structures and make coding and reading a program for scientists, not computer nerds, as natural as possible.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 21:08 UTC (Wed) by sfeam (subscriber, #2841) [Link]

I can imagine issues with passing arrays and corresponding indices to a C-language library from a julia program. Is there some guidance in the language design documents on this point, if only at the level of "don't do that"?

An introduction to the Julia language, part 1

Posted Aug 29, 2018 21:22 UTC (Wed) by rweikusat2 (subscriber, #117920) [Link] (4 responses)

Merely restating your wrong assertions and adding some new ones (eg, as opposed to what you claim, the Dijkstra text is not about machine language at all but about interval notations and high-level programming languages) doesn't make them any less wrong than they were.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 23:11 UTC (Wed) by danielpf (guest, #4723) [Link] (2 responses)

Stating wrong again without listening is not making your statements any more valid.
Assembly language *level* is not the same as assembly language for instance.

You seem just unable to take the viewpoint of people not caring about memory indexing
which is at the level of assembly language, or C, but ideally would like to work with
more abstract objects like vectors, tensors, linear operators, etc.

Do you really think that the designers of higher level languages aimed at scientists like Mathematica,
Maple, Matlab/Octave did not seriously consider what is the best way to address arrays for their
intended users? Apparently the Julia designers did and opted also against 0-based indexing.


An introduction to the Julia language, part 1

Posted Aug 29, 2018 23:23 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link] (1 responses)

> Do you really think that the designers of higher level languages aimed at scientists like Mathematica, Maple, Matlab/Octave did not seriously consider what is the best way to address arrays for their intended users?
Yep.

> Apparently the Julia designers did and opted also against 0-based indexing.
They were trying to keep the language easier for former Matlab users to pick up.

An introduction to the Julia language, part 1

Posted Sep 10, 2018 22:19 UTC (Mon) by VITTUIX-MAN (guest, #82895) [Link]

I take you get his point though. When you do more mathy stuff, you get less offset by one errors with 1-indexing, whereas C-thinking people, what most computer people are, say likewise that of course 0-indexing is natural.

Engineers dislike Matlab too, because we too start from 0 usually.

An introduction to the Julia language, part 1

Posted Sep 7, 2018 8:13 UTC (Fri) by marcH (subscriber, #57642) [Link]

> Merely restating your wrong assertions and adding some new ones doesn't make them any less wrong than they were.

In any case your tone makes sure the points you're trying to make start with a significant disadvantage.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 17:09 UTC (Thu) by mgb (guest, #3226) [Link] (12 responses)

In both the real world and the computer world we measure sizes using cardinals starting with 0 for empty.

In both the real world and the computer world we designate elements using ordinals starting with 1 for the first element. We do this as a convenience so that after designating N objects we know their cardinality to be N but we could if we wished designate the first element as 0 or -11 or "penguin".

In both the real world and sensible computer languages we locate starting with ordinates starting from mile 0, degree 0, 0 inches on a ruler, or position 0 in an array.

Confused computer languages locate elements in arrays starting from 1, although arrays are for locating, not designating. (To designate you'd use a mapping from element to ordinal.)

What is surprising is that confused computer languages are often deliberately targeted to annoy mathematicians who have a rigorous understanding of ordinals, cardinals, and ordinates.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 17:37 UTC (Thu) by danielpf (guest, #4723) [Link]

Gee, your real world is not mine. Your post is so full of definitive statements that a useful discussion looks impossible.
Perhaps the familiarity with binary logic makes some people unable to nuance.

0 versus 1, the eternal battle

Posted Aug 31, 2018 15:07 UTC (Fri) by hackerb9 (guest, #21928) [Link] (4 responses)

That's an interesting take on locating versus designating but, not being a mathematician, it seems to me like your argument would actually argue for a 1-based index. Don't mathematicians usually designate elements of arrays starting from 1, such as a₁, a₂, a₃, …, an? And do they not primarily use the designations, not the locations, when writing about mathematics? It follows then that in a piece of code they would find it easiest to simply refer to them as a[1], a[2], a[3], …, a[n], would it not?

____
Footnote: Personally, as a computer scientist, 1-based indices hurt my head, but I think Julia looks awesome enough that I'm going to dive in and give it a shot. Who knows, maybe I'll be converted and have to create a new programming language in which apenguin is the first element.

0 versus 1, the eternal battle

Posted Aug 31, 2018 16:58 UTC (Fri) by danielpf (guest, #4723) [Link]

A modern language like Julia allows to take an arbitrary sequence or set of any type, and loop over it.
Also any label can index the elements of a table.

In pseudocode it reads like

From Monday to Friday do ... end,

From "a" to "r" do ... end

Age[John]

When operating over structures one can need either global operations such as

A = sin(B) + 1

where A and B are structures (could be arrays), or one needs to operate on a subset of the structures
determined by a condition (for example all the prime numbers in array A are set to 0: A(isprime) = 0).
In such frequent cases the way the elements are addressed is irrelevant.

So the higher level people program the less relevant the indexing is.

0 versus 1, the eternal battle

Posted Aug 31, 2018 17:39 UTC (Fri) by mgb (guest, #3226) [Link]

a₁, a₂, a₃, … is a sequence. Sequences often start with a₁ but this is not always the case. However a sequence is a function, not an array.

If a sequence is finite you can represent or even define the function by an array of values but you'll usually want to work with with an expression defining the function.

(x, y, z) is a kind of finite sequence but in a high-level language you're probably going to access the ordinates by name or implicitly iterate over them rather than accessing them as (a₁, a₂, a₃).

0 versus 1, the eternal battle

Posted Sep 6, 2018 5:25 UTC (Thu) by bjlucier (subscriber, #5281) [Link]

You might look at the Scheme language SRFI 122

https://srfi.schemers.org/srfi-122/

which contains my suggested way to work with arrays. Not quite a_penguin, but almost.

0 versus 1, the eternal battle

Posted Sep 6, 2018 6:33 UTC (Thu) by Wol (subscriber, #4433) [Link]

> Don't mathematicians usually designate elements of arrays starting from 1, such as a₁, a₂, a₃, …, an?

This is a LIST. Arrays are usually used to store lists. Lists don't exist in relational theory, and arrays are second class citizens in C. Hence relational/C guys don't understand why people should want to start at 1 :-)

Cheers,
Wol

An introduction to the Julia language, part 1

Posted Sep 6, 2018 6:31 UTC (Thu) by Wol (subscriber, #4433) [Link] (5 responses)

> In both the real world and the computer world we measure sizes using cardinals starting with 0 for empty.

And how many ordinary people do you know in your "real world"?

In my real world, most people aren't interested in maths. In my real world an object with size 0 usually doesn't exist. In my real world I would be tearing my hair out if I tried to explain why counting from 0 made sense.

Yes, I count from 0 when programming in C. But my preferred language "sort of" starts counting from 1 - arrays have an element(0), but that's all arrays, including two- and three-dimensional arrays! And the language does fancy things with element 0, precisely because it doesn't make sense to have an element 0 in normal use - you don't have a zero-th element in a list. (Programmers - database guys especially - seem fixated on sets, which because they don't have order, lack the concept of counting FROM ONE.)

And when I'm programming *for* the real world, an array location of 0 actually almost never makes sense. There's a reason C says an array and a pointer are equivalent - 0 makes sense for pointers, it does NOT make sense for arrays, and as someone who knows both C and FORTRAN as first-class languages, I always find it weird using arrays in C precisely because it is a pointer-based language, whereas the concept of pointers is totally alien to FORTRAN.

As an assembly-level language C doesn't hide the fact that *internally* arrays start at 0. But it's a damn sight easier to use a higher level compiler (like FORTRAN) to hide that fact from the user, because if the user is not a professional programmer (ie most FORTRAN guys, and Julia's target audience) they have no need to know that.

Cheers,
Wol

An introduction to the Julia language, part 1

Posted Sep 6, 2018 16:32 UTC (Thu) by mgb (guest, #3226) [Link] (4 responses)

And yet in the real world beyond FORTRAN we do measure sizes starting with 0 for empty and we do measure locations starting from 0 inches, 0 miles, and 0 degrees.

An introduction to the Julia language, part 1

Posted Sep 21, 2018 18:32 UTC (Fri) by ssmith32 (subscriber, #72404) [Link] (3 responses)

I don't ever recall seeing a mile 0 mile marker on the road. Mile 1, Mile 500, etc, yes. Mile 0?

(Or kilometer, or feet, depending on your activity & country).

I will grant that, when diving, you can have a depth of zero, but that's the only example I can think of ..

I never climbed a zero foot rock wall. Or used a 0 foot rope when doing so.

Please elaborate with examples...

An introduction to the Julia language, part 1

Posted Sep 21, 2018 18:35 UTC (Fri) by pizza (subscriber, #46) [Link]

> I don't ever recall seeing a mile 0 mile marker on the road. Mile 1, Mile 500, etc, yes. Mile 0?

There's a particularly famous one in Key West, Florida. (At the start of US Highway 1)

An introduction to the Julia language, part 1

Posted Sep 21, 2018 18:40 UTC (Fri) by jake (editor, #205) [Link]

Exit 0 on the Garden State Parkway ... Cape May, NJ ...

other places as well ...

jake

An introduction to the Julia language, part 1

Posted Sep 21, 2018 19:04 UTC (Fri) by Cyberax (✭ supporter ✭, #52523) [Link]

> I don't ever recall seeing a mile 0 mile marker on the road. Mile 1, Mile 500, etc, yes. Mile 0?
Lots of cities in Russia have them. There's a famous one in Moscow: https://commons.wikimedia.org/wiki/File:0_Kilometer_Point...

An introduction to the Julia language, part 1

Posted Aug 31, 2018 20:52 UTC (Fri) by rschroev (subscriber, #4164) [Link] (2 responses)

I'm not going to argue for or agains 0-based or 1-based indexing, I just want to point something out:

> And scientists are like normal people, they mostly don't care about the assembly language level elegance that Prof. Dijkstra was promoting.

Did you read EWD831, "Why numbering should start at zero" (http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx...)? Dijkstra's arguments are completely language-independent, and are rather abstract and high level. I don't understand where you get the notion that his reasoning has anything to do with assembly language level. And I certainly don't understand how/where Dijkstra was promoting assembly language level elegance. You're not confusing things with Donald Knuth's MIX and MMIX, I hope.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 22:56 UTC (Fri) by danielpf (guest, #4723) [Link] (1 responses)

> Did you read EWD831, "Why numbering should start at zero" (http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx...)?

Yes I did long long ago. I have programmed scientific applications in many languages (Basic, Algol, Pascal, C, Fortran, PLI, APL, Lisp, Forth, for some of the oldest) over decades and did not find Dijkstra arguments compelling. In practice the most convenient indexing scheme depends on the problem. Sometimes one would like to index arrays starting with negative numbers, or using other sequences, like x,y,z.
For some other problems (say indexing the day of the month) starting with 1 is the most obvious.
Forcing scientists and other users to count with a single rigid scheme while the compiler can easily do the translation is, like programming in assembler, wasting neurones: it distracts from higher level considerations.

Fortunately Julia, like Matlab or Fortran, allows to operate on arrays and other structures as global objects, or index them with complex conditions, so it is less and less necessary to care about the default indexing basis.

For example a matrix product in Julia or Matlab takes one line:
julia> X = A*B

The equivalent C code requires several lines, 3 loops, 3 indexes, where the 0-based indexing must
be respected as well as the matrix dimensions, and of course is far less optimal for large matrices
than what is done internally by Julia.

sum = 0;
for (i = 0; i < m; i++) {
for (j = 0; j < q; j++) {
for (k = 0; k < p; k++) {
sum = sum + A[c][k]*B[k][d];
}
X[c][d] = sum;
sum = 0;
}
}

So the way out of the 1- or 0-indexing discussion is to program at higher level than indices when possible, and to have the freedom to choose the starting index when not possible.

An introduction to the Julia language, part 1

Posted Sep 1, 2018 9:02 UTC (Sat) by rschroev (subscriber, #4164) [Link]

I see where you're coming from. Yes, modern languages in many cases don't require you to index at all, so I guess you could say that any indexing you do need is low level. That doesn't make Dijkstra's reasoning low level, I think, but I see your point.

Thanks for clarifying.

An introduction to the Julia language, part 1

Posted Sep 6, 2018 15:55 UTC (Thu) by fgrosshans (guest, #35486) [Link]

> "Prehistoric" means "we know nothing about it save what can be deduced/ inferred from artefacts because there are no written records dating back to this time". If you knew how people had counted in prehistoric times, they thus wouldn't have been prehistoric.
> That's a contradictio in adiecto.

No, it is not a contradiction. Written record does NOT mean no data. For example, comparative linguistic, tells us about languages before they get attested in writing. If one looks, for example, at the best known language families (but it is also true for others), one can see related words for numbers (both cardinals and ordinals) starting at one, the words for zero appearing much later, in historical time. Form this data, it is difficult to conceive widespread prehistoric zero-indexed counting practice, which would simultaneously disappear across these wide-spread and non-communicating civilizations with the invention of writing.

Another counter-example is proto-historic Mesopotamia, where we have written/material notation of numbers centuries before this number notations evolved into a full writing systems, which included a zero, but later and only in technical texts.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 20:07 UTC (Wed) by Cyberax (✭ supporter ✭, #52523) [Link]

0-based indexing makes it MUCH easier to do array manipulation because position within an array and the offset from its start are the same. It's not true for 1-based indexing (the first position is "1" but its offset is "0").

It's easy to illustrate, for example, on a simple circular buffer:
C: buf[pos % BUF_SIZE] = 1
Pascal: buf[(pos-1) mod BUF_SIZE + 1] = 1

An introduction to the Julia language, part 1

Posted Aug 30, 2018 2:05 UTC (Thu) by neilbrown (subscriber, #359) [Link]

> Indeed almost everybody count sheeps, stones or people starting with 1, not 0.

Do they? Do they really?
I'm reminded of a line from the children's novel "The Silver Chair" by C.S.Lewis.

> "We've got to start by finding a ruined city of giants," said Jill. "Aslan said so."
>
> "Got to start by finding it, have we?" answered Puddleglum. "Not allowed to start by looking for it, I suppose?"
>
> "That's what I meant, of course," said Jill.

What does a person have in their mind before they see the first sheep (or stone or person)? Maybe the first thing they *say* is "one", but there is an understanding that they have started the process before the "one" is said. That "understanding" is effectively "zero", even when not explicit. "That's what I mean, of course," said Jill.

It only makes sense to start at "one" when using ordinal numbers: first, second, third. "zeroeth" really doesn't exist except as a joke. With cardinal numbers, it only ever makes sense to use a number that represents a count of things.
So when I'm counting sheep, I say the number of sheep that I have seen, though I might not bother saying all the numbers out loud (who among us has counted "2, 4, 6 ..." because it seemed a waste of effort to say the numbers in between).

If you think of the indexes to arrays as ordinal numbers, then it is appropriate to use "1", "2", "3" as short-hand for "first", "second", "third".
I like to use cardinal numbers - each location is named by the count of slots before it. The first element has zero slots before it, so it is named "element zero".
This "count of slots before it" might seem clumsy, but if you ever try to write loop invariants (and really, you should - even if you don't write them down), you will find that it turns out to make the maths much cleaner.
Maths generally works better with cardinal numbers than with ordinal numbers.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 7:19 UTC (Thu) by jem (subscriber, #24231) [Link] (3 responses)

The problem is not the wasted memory word, or how much energy and time an increment costs. The problem is the explicit and error prone +1s and -1s in your code, when working with 1-based vectors and matrices on a problem that is better suited for 0-based indexing. There are a lot of problems like this; the Discrete Fourier Transform, for example.

Ok, so Julia apparently allows you to use 0-based indexing, good. When I first read about Julia, the 1-based indexing seemed like wart to me. It's like a car odometer that displays "1" before the car has moved a single meter.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 9:53 UTC (Thu) by danielpf (guest, #4723) [Link] (2 responses)

>The problem is not the wasted memory word, or how much energy and time an increment costs. The problem is the explicit and error prone +1s and -1s in your code, when working with 1-based vectors and matrices on a problem that is better suited for 0-based indexing. There are a lot of problems like this; the Discrete Fourier Transform, for example.

This is a legend, because the +1 bug occurs in any language. For example in 0-based indexing you loop from 0 to N-1, so you must not forget the -1. I have programmed scientific applications in many languages overs decades and found that both kinds of indexing offer advantages and disadvantages in different contexts. In both indexing ways the +1 bug is lurking.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 6:19 UTC (Fri) by epa (subscriber, #39769) [Link] (1 responses)

Typically in languages with 0-based indexing the idiom will be to use a < comparison for the upper bound, as

for (int i = 0; i < N; i++)

So N-1 isn’t usually needed.

A neat helper, too, is Python’s half-closed range for list slices, a[n:m] giving m-n elements. This is more convenient than a .. inclusive range for many programming tasks.

An introduction to the Julia language, part 1

Posted Sep 6, 2018 6:43 UTC (Thu) by Wol (subscriber, #4433) [Link]

> Typically in languages with 0-based indexing the idiom will be to use a < comparison for the upper bound

Which is a trap for the unwary, or noob.

All languages have idioms. I once wrote a piece of code - in a class for C beginners - that effectively did

count = 0
for i = 1 to 13
count += (cardvalue == 3)
next

to find out how many threes were in the hand. I just could not get the lecturer to write the addition line correctly on the board until I told him to write it down, character by character, as I spelt it out. To me, that idiom is second nature, to him it was totally alien.

And yet, it SHOULD be completely natural to users of any language (like C) where the language defines the result "true" as being represented by the integer "1". (Note I said "result" not "value" ...)

and you'll find plenty of C programmers to whom the "<" idiom is alien, until they've been programming in C for quite a while and had it rammed in to them.

Cheers,
Wol

An introduction to the Julia language, part 1

Posted Aug 30, 2018 18:15 UTC (Thu) by kvaml (guest, #61841) [Link] (4 responses)

Ancient folks knew how to count things: sheep, sheaves, bricks. Their numeric notation had no zero. They were confused about dealing with sequences.

The gospels reflect different views about counting days. Matthew and Mark count the days between events and exclude the beginning and ending days. Luke includes the beginning and ending days.

Suppose you were playing Monopoly with Mark and Luke and you all rolled sevens. Mark would count Mediterranean AVE as one,...,Community Chest as seven and then advance to Vermont Ave. Luke would count GO as one,... Oriental Ave as seven and remain there. You would count Mediterranean Ave as one and wind up on Community Chest.

The ancients placed the birth of Christ in year one AD. The prior year is year is year one BC. They were using roman numerals and had no zero.

Counting like the ancients has its pitfalls.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 2:39 UTC (Fri) by neilbrown (subscriber, #359) [Link] (3 responses)

I wasn't there, so I cannot be sure, but I don't think they counted days at all (unlike sheep). Rather they enumerated (assigned numbers to) days and times.
So you get "On the first day of the week" or "on the third day" or "at the 6th hour".

If you look at our modern calendar, years, months, and days are all set up for ordinal naming, while our modern clock sets hours, minutes, and second up for counting (well... hours are a bit confused - for the military they fall towards counting, for civil use they are a bit more like naming).

If you select some moment to mark the epoch, then the twelve months following would comprise the "First year after the epoch" and the preceding twelve months would be the "First year before the epoch". This perfectly explains "1 BC" being followed by "1 AD".

I have heard that even now the traditional approach to giving the age of a person in Chinese culture, is that they are "1" from birth until the new year, then "2" until the next new year, and so forth. This is probably a poor translation.
It makes perfect sense to be "in their first year" until new year, then "in their second year", and so forth. Is there anyone with better knowledge of Chinese culture who can confirm or deny? Thanks!

An introduction to the Julia language, part 1

Posted Aug 31, 2018 3:17 UTC (Fri) by dtlin (subscriber, #36537) [Link]

Can confirm. Yes, traditionally you are 一歲 at birth, 二歲 at Lunar New Year, 三歲 the year after, and so on. It's no longer used for modern or legal purposes, I think I've only heard it with my grandparents' generation or in divination.

https://en.wikipedia.org/wiki/East_Asian_age_reckoning

An introduction to the Julia language, part 1

Posted Aug 31, 2018 20:35 UTC (Fri) by epa (subscriber, #39769) [Link]

The idiom of "in your fortieth year" is also known in English (and even the 1-based year numbering is explained by the long form, the two thousand and eighteenth year of Our Lord). Also, of course, your first birthday is not really your first.

An introduction to the Julia language, part 1

Posted Sep 6, 2018 2:34 UTC (Thu) by kvaml (guest, #61841) [Link]

Mark and Luke were counting days between events in their narratives. They disagreed on how that count should be performed.

Ancients lacked zero and lived before Descartes. Insisting that we should continue to count as they did is probably a mistake.

An introduction to the Julia language, part 1

Posted Sep 6, 2018 10:16 UTC (Thu) by oldtomas (guest, #72579) [Link]

> The 1-based indexing has been used in mathematics for ages because [...]

Translation: "My preference is The Way God Intended, so everyone should do it My Way". Not very convincing, is it?

> The 0-based indexing was only thought a clever idea because then you can avoid "wasting" a memory word,

Bzzzt. Wrong. When I started my studies (physics, maths), 1975 (four years after C), most languages around indexed still from 1. Language implementors were no idiots (even back then, go figure!) and didn't leave "word zero" empty just to start counting from one.

Our maths faculty counted from zero, physicists were half this, half that way.

My observation since then is that math faculties tend to vary between counting from one or from zero; those strong in mathematical logic and model theory seem to prefer zero.

My take is: I clearly prefer zero to be a natural number. But starting a holy war on this is the worst of all three choices.

Come on: you can do better than that.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 16:08 UTC (Thu) by rsidd (subscriber, #2582) [Link] (9 responses)

Replying to multiple comments above -- I get the feeling most of the critics do not do scientific programming.

Cyberax:

C: buf[pos % BUF_SIZE] = 1
Pascal: buf[(pos-1) mod BUF_SIZE + 1] = 1
This is not something a scientific programmer will commonly do, and if it is occasionally required, it is easy enough. Easily worth the tradeoff with intuitive indexing.

Various people supplying EWD quotes: he was not a scientific programmer.

neilbrown:

What does a person have in their mind before they see the first sheep (or stone or person)? Maybe the first thing they *say* is "one"
And they say that when they see the first sheep. If there is one sheep, that is sheep number one. Not sheep number zero. (I can't believe that needs to be spelled out.)

jem:

The problem is the explicit and error prone +1s and -1s in your code, when working with 1-based vectors and matrices on a problem that is better suited for 0-based indexing. There are a lot of problems like this; the Discrete Fourier Transform, for example.
Yes, that is in fact a good example. Any others? I'd say DFT/FFT is very much the exception and, anyway, users are highly likely to use libraries for this. It should not be the basis for policy.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 16:52 UTC (Thu) by leephillips (subscriber, #100450) [Link]

Indeed—and to paraphrase a comment one of the Julia developers made to me once, Julia was designed more to address the problems of computational science, rather than computer science.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 2:47 UTC (Fri) by neilbrown (subscriber, #359) [Link]

> And they say that when they see the first sheep.

Yes,. exactly. "First".
"First" and "One" are different things. They seem similar and for many practical purposes, the difference doesn't matter. But "off-by-one" errors are a thing, and my pet theory is that they are often caused by a confusion between ordinals and cardinals.

This is most often seen when we ask "how many days from the 4th to the 10th of the month"?? Surely it is a 6... or is it 7. Or what does the question even mean?
Travel agents work around the problem by saying there are 6 nights between the 4th and the 10th, and try to avoid committing to a number of days.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 7:24 UTC (Fri) by Cyberax (✭ supporter ✭, #52523) [Link]

Certain areas do need a lot of index operations. I’m personally familiar with molecular biology and computational chemistry.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 8:22 UTC (Fri) by jem (subscriber, #24231) [Link] (4 responses)

> Any others?

Just about anything cyclic. Let's say you keep a count of events classified by during which hour of the day they happened. Do you use an array with indices 0..23 or 1..24? (Or maybe two arrays, am and pm, each with indices 12,1,2,3,4,5,6,7,8,9,10,11?)

An introduction to the Julia language, part 1

Posted Aug 31, 2018 10:44 UTC (Fri) by geert (subscriber, #98403) [Link]

Especially when the "12" comes first in your sequence. Leads to lots of confusion about "12PM" and "12AM".
Great for conference calls in multiple time zones. You won't be the first to join the meeting one day early or one day late ;-)

An introduction to the Julia language, part 1

Posted Aug 31, 2018 15:26 UTC (Fri) by hackerb9 (guest, #21928) [Link] (2 responses)

Or do it like I've been told the U.S. Army does: 0..24. 0 and 24 refer to the same hour, but they use them to make the rest of the context consistent: for example, We are meeting in the War Room from 23:00 to 24:00 and then having an ice cream social from 0:00 to 1:00.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 15:59 UTC (Fri) by farnz (subscriber, #17727) [Link] (1 responses)

Or go further, as some places in Japan do. A bar can be open (say) 1800 to 2700, meaning in 12 hour terms "from 6pm today until 3am tomorrow"; similarly, a long distance transit route might have the last vehicle today leaving at 2330 and arriving at 2530 (meaning 0130 tomorrow), while the next vehicle leaves at 0015 and arrives at 0215.

Basically, today started at 0000 - time then runs continuously so that 2530 today is the same as 0130 tomorrow, and 4930 today is the same as 0130 in two days time.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 16:08 UTC (Fri) by rsidd (subscriber, #2582) [Link]

Ok, here's what many of you are missing. Arrays are discrete. Time is continuous -- eg hours, years, which can exist non-integrally. So is the FFT (ok, it's discrete but it's an approximation for a continuous thing.)

Zero-indexing makes sense for "discretized" continuous or periodic things. It makes sense to label the first hour after midnight the zero hour: the markers are 0 and 1, at either end, and even for continuous periodic things, the "mod" argument makes some sense for zero-indexing.

For sequences in general, nobody refers to "a" as the zeroth letter in the word "algorithm". It is the first letter. This is just how daily language works and also how mathematical notation works for the most part. The FFT may start from a zero-index but that's fundamentally because it's based on an assumption that the sequence is periodic. Vectors are always 1-indexed, except in relativity where time gets the index 0 while spatial indices are 1,2,3 -- and that too is for historic reasons (originally time was 4, but in imaginary units; when they figured it's better to use real units and a non-Euclidean metric, they chose 0 to avoid confusion.)

An introduction to the Julia language, part 1

Posted Sep 3, 2018 18:58 UTC (Mon) by togga (guest, #53103) [Link]

"This is not something a scientific programmer will commonly do"

Really?

I guess this "scientific programmer" will not commonly integrate different components from different languages either. Nor does this "programmer" commonly need to map anything to a memory model (protocol, disk-layout, ...). This "scientific programmer" you describe seem very limited to me.

Is Julia designed to be a programming language aimed for computers or for mathematicians that don't want to change old habits inherited from a time before computers existed?

An introduction to the Julia language, part 1

Posted Aug 29, 2018 9:52 UTC (Wed) by danielpf (guest, #4723) [Link] (6 responses)

I am glad that Julia developpers made many choices right as seen from a computational scientist viewpoint.

There is yet still an inconsistent decision regarding copying or linking new arrays.
A code like this using arrays of size 1

julia> A = [1]; B = A .+ 0 ; B[1]=2; A,B
([1], [2])
is not equivalent to a code like this
julia> A = [1]; B = A ; B[1]=2; A,B
([2], [2])

which is not equivalent to a code using scalars

julia> A = 1; B = A ; B=2; A,B
(1, 2)

What is inconsistent is to use the same symbol "=" for different operations, copying or linking, depending on the data type.

Matlab/Octave is consistent on the other hand.

A situation which occurs frequently is when assigning new arrays. Typically one wants to set several distinct arrays of
same size to an initial value.
Instead of doing
julia> A = B = zeros(2,3);

one needs do repeat
julia> A = zeros(2,3); B = zeros(2,3);

An introduction to the Julia language, part 1

Posted Aug 29, 2018 11:18 UTC (Wed) by rsidd (subscriber, #2582) [Link] (5 responses)

Julia does copying for primitive types, linking for everything else, as I understand it -- basically for efficiency reasons. If you want a copy, there are the copy() and deepcopy() functions (you can define shorthands if you use them a lot). True, you can't use "A = B = zeros(2,3)" when what you want is a copy... Yes, it can be a source of bugs initially. But once one is past the learning curve, I don't see this as a huge problem.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 13:06 UTC (Wed) by danielpf (guest, #4723) [Link] (3 responses)

I have heard the efficiency argument, but rarely seen cases where this really matters. Most of the time when two arrays with different names are used it is because they need distinct memory. This efficiency argument reminds me of the arguments for the Fortran COMMON statement, which has for long been deprecated because introducing bugs and obscuring programs.
This is just inconsistent to use the same operator (=) for distinct operations depending on the data type.
If one needs to link two arrays for efficiency reason let an operator like "<-" explicitly express the programmer decision,
this would be way clearer.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 14:16 UTC (Wed) by leephillips (subscriber, #100450) [Link] (2 responses)

Python (for example) behaves in exactly the same way. You need to know about the data types you are using, and that arrays are mutable. It is very common in Fortran code to use different names for the same array, or, more commonly, for segments of an array.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 14:45 UTC (Wed) by danielpf (guest, #4723) [Link]

Yes Python is subject to the same inconsistency, but not Matlab which is taylored for scientific computations.
In Fortran A = B is actually a *copy* also for arrays unless you have declared and explicit EQUIVALENCE,
this is much clearer :

-------------------------------------
Program TEST
DIMENSION A(2), B(2)
! EQUIVALENCE (A,B)

A = 0.
B = A
A(1) = 1.
print *, A, B

END program

--------------------------------------

$ gfortran test.f90
$ ./a.out
1.00000000 0.00000000 0.00000000 0.00000000


An introduction to the Julia language, part 1

Posted Sep 2, 2018 3:03 UTC (Sun) by droundy (subscriber, #4559) [Link]

Yes, and as someone who teaches computational physics using python, this is probably the worst problem in terms of confusing students and introducing bugs that students are unable to track down. It seems a terrible idea to reproduce this bug in a language specifically intended for scientists with little training in programming.

An introduction to the Julia language, part 1

Posted Sep 19, 2018 19:16 UTC (Wed) by mcortese (guest, #52099) [Link]

Can someone come up with an example where one needs A=B to be a link instead of a copy?

An introduction to the Julia language, part 1

Posted Aug 29, 2018 12:44 UTC (Wed) by milesrout (subscriber, #126894) [Link] (6 responses)

Pity to see so many comments focusing on trivial syntactic issues like the indexes. I'm only surprised there aren't twice as many focusing on the syntax of the comments as per Wadler's law. From what I have seen, Julia's standard library (and the major libraries) are all written to be indexing-agnostic.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 13:17 UTC (Wed) by Paf (subscriber, #91811) [Link] (4 responses)

I really, really don’t think it’s practical long term to have switchable indexing. Not everything will work with it, especially outside of the standard libraries. However careful they are, others will not even bother.

But that’s not fatal or anything - it’ll just end up as a 1 based language with a few angry holdouts switching it to 0 and struggling with non standard library code (of which one hopes there will be a lot, if the language is to really succeed), It’s just I think the switching ability isn’t a good idea, it’s a mild misfeature - it largely opens the possibility of frustration rather than benefit.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 15:28 UTC (Wed) by leephillips (subscriber, #100450) [Link] (3 responses)

Well, Fortran has been considered practical long term, and there you can index arrays any way you want - even with negative indices.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 17:11 UTC (Wed) by Paf (subscriber, #91811) [Link]

Good point.

Looking at Julia, it appears roughly that the alternately indexed arrays are an explicitly different kind of object from regular arrays...? That seems much better than what it seemed others were describing.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 4:25 UTC (Fri) by cry_regarder (subscriber, #50545) [Link]

By the way, I have found arbitrary indexing to be handy for naturally expressing dynamic programming tableaus and pre-built recursive bases. The code naturally matches the math.

I've worked around it in fixed index languages by having a constant holding the offset:

o = 3
i[0 +o] = i[-3 +o] + i[-1 +o]

ugly but readable against the maths.

An introduction to the Julia language, part 1

Posted Sep 6, 2018 6:52 UTC (Thu) by Wol (subscriber, #4433) [Link]

> Fortran has been considered practical long term, and there you can index arrays any way you want - even with negative indices

And FORTRAN is 1-based and you can't change the index. They were prepared to change and break things when they went from FORTRAN to Fortran, yet this is something they extended rather than broke.

(Don't feed a FORTRAN loop into a Fortran compiler and expect it to work! Incidentally this is 1 or 0 based - a FORTRAN loop is 1-based while a Fortran loop is 0-based :-)

Cheers,
Wol

An introduction to the Julia language, part 1

Posted Aug 29, 2018 21:40 UTC (Wed) by k8to (guest, #15413) [Link]

For my part it was just an idle comment about the indexing. I don't think 1-based indexing is important in terms of a detriment.

I'm not a big fan of having there be multiple indexing conventions though. Just seems like more cognitive load. But maybe it isn't in its targetted domain.

An introduction to the Julia language, part 1

Posted Aug 29, 2018 17:15 UTC (Wed) by raegis (guest, #19594) [Link]

OK, I just downloaded Julia. Two quick comparisons with Octave.

In Julia it looks like ^ is right-associative:

julia> 3^2^3
6561

while in Octave ^ is left-associative:

>> 3^2^3
ans = 729

Another example which had me stumped for several minutes: In Julia,

julia> [1,2]*[1,2]'
2×2 Array{Int64,2}:
1 2
2 4

but in Octave,

>> [1,2]*[1,2]'
ans = 5

I see now the style in Julia is different. Commas and semicolons in Julia seem to delimit rows, but in Octave commas are optional, so

julia> [1 2]*[1 2]'
1×1 Array{Int64,2}:
5

is correct for the example.

I'm not blaming Julia, but it looks like there will be some surprises for those coming from other systems.

An introduction to the Julia language, part 1

Posted Aug 30, 2018 10:35 UTC (Thu) by cagrazia (guest, #124754) [Link] (2 responses)

     while i < 5
            print(i)
            global i = i + 1
      end
but... i is undefined in the first line... how can the loop start?

An introduction to the Julia language, part 1

Posted Aug 30, 2018 12:07 UTC (Thu) by leephillips (subscriber, #100450) [Link] (1 responses)

On the line before the block:

julia> i = 1;

.... in the global scope of the REPL.

An introduction to the Julia language, part 1

Posted Sep 2, 2018 21:20 UTC (Sun) by billygout (guest, #70918) [Link]

What's more confusing to me is that `global` was needed in the assignment statement in the loop, but not in the first line in the loop `print(i)`. Why would that be?

An introduction to the Julia language, part 1

Posted Aug 31, 2018 17:36 UTC (Fri) by hackerb9 (guest, #21928) [Link] (4 responses)

This was a timely and helpful article for me.

Every so often, the language I've been using becomes encrusted with extra requirements that make programming less joyful but safer for, say, a nuclear power reactor. Since I don't program nuclear power reactors, this has sometimes led to me shifting my coding preferences.

In the early days, Python started out looking very much like executable pseudocode, which I thought was fabulous. But now, as it has "matured", it makes the programmer specify more things that have nothing to do with the heart of the algorithm. Even C, which is pretty ugly nowadays with all the mandatory casts and declarations, was much more readable, almost beautiful, back when it was invented.

Maybe some day programming languages will have dynamically expandable footnotes and we can encapsulate all the ugly (but necessary) details in some hidden away spot that won't distract from the main point we're expressing. It's kind of ridiculous that most of programming today uses pretty much the same typography capabilities of Hollerith punchcards.

Until that day, Julia looks pretty awesome, at least in its 1.0 state. In terms of being able to powerfully express concepts in a natural way and with a minimum of mandatory cruft, it has Python beat. It's so far been as close to C in speed as I need and much faster than Octave and Numpy. I love that the REPL command line works the way I expect and already know: tab completion, LaTeX to express Unicode (while ɛ> ♥ <3), emacs editing key sequences, history, multiline editing, defaults to printing to console if no semicolon, and on and on.

And, can I just say, that I love having a language the properly treats Unicode as the default instead of ASCII. I can talk about ℵ₀ ∈ ⅄ or use a variable named ɛ when that's what I mean instead of spelling it out in English ("epsilonButYouKnowThatBackwardsThreeVariant"). Although, I do kind of wish Julia did not use Unicode for subscripts, as it is rather lacking. For example, you can't write dBSPL. Also, to me subscripts are the most compact and readable way to specify the index into an array, as in: ai = ai-1 + ai-2. If they were going to support subscripts in a mathematical language it would have been nice to have it be as a syntactical alternative to using square brackets.

All in all, I think Julia is a strong contender to be my language of choice over the next decade, or until it becomes old and ossified. I did notice one little annoyance already. The print function cares whether there is a space before the open parenthesis. Apparently this is a new thing as it complains that I'm using "deprecated" syntax. I can live with it, but I hope it doesn't foreshadow Julia 2.0 becoming even more naggy and less natural.

An introduction to the Julia language, part 1

Posted Aug 31, 2018 19:22 UTC (Fri) by leephillips (subscriber, #100450) [Link]

Thanks for that interesting comment. I wonder if it would be possible to create subscript indexing with macros. Have you looked into Donald Knuth's literate programming system? Your remarks suggest that it might interest you if you haven't.

'But now, as it [Python] has "matured", it makes the programmer specify more things that have nothing to do with the heart of the algorithm.'

Can you give an example of what you mean?

An introduction to the Julia language, part 1

Posted Sep 1, 2018 19:35 UTC (Sat) by cpitrat (subscriber, #116459) [Link] (2 responses)

I've often heard the 'I don't write critical code, I don't need all your safety practices' or 'seriously, why would I need unit tests ?' from researchers, including some in computer science. One of them once published a paper and a few months later, another researcher contacted him telling he couldn't reproduce the result and whether he would share his code. It turns out he found multiple bugs that made his result invalid. It turns out you should care about your code quality even when you're not writing code for a nuclear reactor.

An introduction to the Julia language, part 1

Posted Sep 1, 2018 20:45 UTC (Sat) by mpr22 (subscriber, #60784) [Link] (1 responses)

The level of "caring about code quality" I would want to be applied to safety-critical software for operating a flight control system, radiotherapy machine, or nuclear reactor is much, much higher than I think is reasonable to apply to, say, a seven-day roguelike :)

An introduction to the Julia language, part 1

Posted Sep 1, 2018 22:47 UTC (Sat) by k8to (guest, #15413) [Link]

Sure, though I agree with the contention that suggests many people give too little care for it across the breadth of coding scenarios. I know I've made the error, and I'm pretty anal retentive about thinking about edge cases and trying things out to validate correctness.

An introduction to the Julia language, part 1

Posted Sep 6, 2018 12:25 UTC (Thu) by CycoJ (guest, #70454) [Link]

Two things that seriously put me off julia last I tried, were:

1. They copied the most infuriating bits of matlab. The 1 vs 0 indexing is maybe a might annoyance, but the stupid use of the "." and " ' " to denote element-wise and transpose is horrible. My numeric programming is to the largest degree not linear algebra, so I mostly want element-wise operations. I can live with the fact that they defaulted to matrices instead of arrays by default (although I would argue they should actually call it properly), however using the '.' is just horrible. When I was still using matlab, I don't know how many hours I was debugging code where it ended up being "search the missing ." They are way too easy to overlook in regular editors but often don't cause your code to crash, but simply give non-sensible results (often not easy to deduce what went wrong). Similarly for the ' as the transpose operator, again a symbol that is way to easy to overlook, but will often not cause a crash but simple wrong results. I see the same errors with the students I supervise who are still using matlab (I know I am doing my best to convert them to use a proper language). This really is a significant development cost.

2. When I tried it a couple of years ago the recommendation for getting the best speed was to unwrap vector operations into loops. Hopefully they fixed that by now, because the reason whey I use a high-level programming language is because I don't want to do explicit loops for multiplying to arrays.

An introduction to the Julia language, part 1

Posted Sep 7, 2018 8:16 UTC (Fri) by marcH (subscriber, #57642) [Link]

> the data overall supports the Julia team's contention that Julia has generally achieved parity with Fortran and C

Is Julia ready for *faster* than C? https://queue.acm.org/detail.cfm?id=3212479

(Fortran already is in some cases)


Copyright © 2018, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds