Magik é uma linguagem de programação orientada a objetos que suporta herança múltipla , polimorfismo e tipagem dinâmica . foi definido e implementado em 1989 por Arthur Chance, da Smallworld Systems Ltd, como parte do sistema de informação geográfica Smallworld. Após a aquisição da Smallworld pela General Electric em 2000, Magik agora é distribuído pela GE Energy , novamente como um componente da plataforma Smallworld.
O Magik foi implementado pela primeira vez em 1990 e foi aprimorado ao longo dos anos. A versão atual é a 4.0, chamada Magik SF (Small Footprint).
Dentro Julho de 2012, os desenvolvedores do Magik anunciaram o porte da linguagem Magik para a máquina virtual Java . O sucesso do porto foi anunciado pela Oracle Corporation em novembro do mesmo ano.
Magik compartilha com Smalltalk , e especialmente com Python, várias semelhanças em termos de funcionalidade e arquitetura:
A máquina virtual Magik está disponível em diferentes plataformas, incluindo Microsoft Windows e diferentes variantes de Unix ou Linux .
Magik é baseado em console e o código pode ser alterado em tempo real, mesmo quando um aplicativo está em execução. O console pode ser usado para executar Magik ou para ver os resultados. O código compilado de um aplicativo pode ser salvo em um único arquivo, denominado arquivo de imagem, ou apenas uma imagem. Uma imagem Magik inclui a definição de classes e variáveis globais e o estado da sessão. Na verdade, este é o estado completo da memória da máquina virtual quando o arquivo de imagem foi salvo.
Magik usa um #para marcar o início de uma linha de comentário. Cada linha de comentário deve começar com # :
# Ceci est un commentaire. # Ceci est un commentaire réparti # sur deux lignesMagik usa o operador <<("torna-se") para atribuições :
a << 1.234 b << b + a c << "foo" + "bar" # Concat stringsEsta notação diz "a torna-se 1.234" ou "b torna-se b mais a". Essa terminologia ajuda a separar a atribuição da comparação.
Magik também implementa um operador compactado semelhante aos existentes em C :
b +<< a # Équivalent à b << b + aPara imprimir o valor de uma variável, você pode usar o seguinte comando:
a << "hello" write(a)Além dos tipos de dados usuais, como inteiros (inteiros), reais (float) ou strings, Magik também implementa símbolos. Os símbolos são usados extensivamente no Magik para identificar objetos de forma única. Eles vêm na forma de um caractere :seguido por uma sequência de caracteres. Os símbolos geralmente consistem nos caracteres az (minúsculas) e _ ,! ou ?. Você pode usar outros caracteres colocando-os entre as barras verticais ( |). Por exemplo :
a << :hello # partout où :hello sera rencontré, il s'agira de la même instance b << :|hello world|Variáveis Magik não são digitadas, pois podem ser em C, C ++ ou Java. Eles podem, como em lisp ou Python, fazer referência a objetos diferentes, de classes diferentes, em momentos diferentes. Magik não diferencia entre classes e tipos primitivos. No Magik, qualquer entidade manipulada é um objeto:
a << 1.2 # Un réel est affecté à la variable 'a' a << "toto" # Puis une chaîne de caractères est affecté à la variable 'a' ObjetosOs objetos são definidos por meio de protótipos chamados “exemplares”. Esses protótipos definem classes, de forma semelhante à definição de classes Python. Magik suporta herança múltipla e classes abstratas ( mixins ). Novas instâncias são definidas pela clonagem de um objeto da classe, geralmente o protótipo, que é uma instância da classe que define, mas qualquer objeto da classe pode ser usado para o mesmo propósito.
o protótipo é definido usando o procedimento def_slotted_exemplar(), por exemplo:
def_slotted_exemplar(:mon_objet, { {:slot_a, 42}, {:slot_b, "bonjour"} }, {:classe_parente_a, :classe_parente_b})Este fragmento de código define uma classe mon_objectque possui dois atributos ("slots") chamados slot_a(pré-inicializado em 42) e slot_b(pré-inicializado "hello") que herda das classes classe_parente_ae classe_parente_b.
Implementos Magik todos os operadores lógicos ( =, <, <=, >, >=, ~=/<>) para comparação, bem como menos comum. Os operadores _ise _isntsão usados para comparar a identidade das instâncias do objeto, em vez de seus valores.
Por exemplo:
a << "Robert" b << "Robert" a _is b # est faux parce que les deux chaînes sont des instances différentes de la classe «chaîne de caractères». a = b # est vrai parce que les deux valeurs sont identiques a << "hello" b << a a _is b # est vrai, puisque les deux variables désignent la même instance (a a été affecté à b). a = b # est vrai, parce que la valeur d'une même instance est forcément identique # (il est impossible d'avoir à la fois a _is b vrai et a=b faux).Os métodos são definidos nos exemplares por meio das palavras _method- chave e _endmethod:
_method mon_objet.ma_methode(a, b) _return a + b _endmethodPor convenção, definimos dois métodos, new()(para criar uma instância) e init()(para inicializar esta instância).
# Méthode d'instanciation _method person.new(name, age) _return _clone.init(name, age) _endmethod # méthode d'initialisation. _private _method person.init(name, age) # utiliser si besoin l'implémentation de la ou des classes parentes. _super(classe_parente_a).init(name, age) # Initialiser les slots. .name << name .age << age _return _self _endmethod_clonecria uma cópia (um clone) da instância personpara a qual a mensagem new () foi enviada. A instrução _superinvoca a implementação do mesmo método na classe pai classe_parente_a. A instância atual é referenciada usando a palavra-chave _self. Os valores dos slots são acessíveis por meio do operador unário ..
Métodos que não fazem parte da interface pública da classe podem ser definidos usando a palavra-chave _private. Os métodos "privados" são acessíveis apenas por meio de _self, _cloneou _super.
Argumentos opcionais podem ser definidos usando a palavra-chave de _optionalinstrução. Nesse caso, os argumentos omitidos terão o valor _unset(o objeto “NUL” de Magik). Uma lista de argumentos variáveis pode ser definida usando o operador_gather ("coletar"), semelhante ao operador * do Python no caso de argumentos variáveis (* args) .
_method my_object.my_method(_gather values) _endmethodEm palavras-chave Magik _for, _over, _loope _endlooppermitem iteração.
_method my_object.my_method(_gather values) total << 0.0 _for a _over values.elements() _loop total +<< a _endloop _return total _endmethod m << my_object.new() x << m.my_method(1.0, 2, 3.0, 4) # x = 10.0Aqui, values.elements () é um iterador que permite navegar pelos valores. Um iterador Magik é um tipo particular de gerador , conhecido como compreensão de lista , geralmente permitindo navegar por um conjunto.
Un itérateur est défini au moyen des mots-clés _itere _loopbody :
_iter _method my_object.even_elements() _for a _over _self.elements() _loop _if a.even? _is _true _then _loopbody(a) _endif _endloop _endmethodComo Python, Magik permite a programação de objeto e / ou iterativa. Magik, portanto, permite a definição de procedimentos. Os procedimentos são definidos usando as palavras _proc- chave e _endproc. Eles são atribuídos a variáveis para que possam ser chamados:
my_procedure << _proc @my_procedure(a, b, c) _return a + b + c _endproc x << my_procedure(1, 2, 3) # x = 6Magik, tendo sido desenvolvido em Cambridge, Reino Unido, usa o inglês britânico em suas bibliotecas. Por exemplo:
Utiliser "initialise", pas "initialize" (en général, les terminaisons sont en "ise", pas ize", utiliser "centre" et non "center", etc.Magik permite a manipulação de conjuntos. Podemos citar:
Aqui está a versão Magik do programa tradicional "Hello world ":
write("Hello World!")