b"\n_START_ARTICLE_\nOz (linguagem de programa\xc3\xa7\xc3\xa3o)\n_START_SECTION_\nModelo de programa\xc3\xa7\xc3\xa3o\n_START_PARAGRAPH_\nO modelo Oz \xc3\xa9 constitu\xc3\xaddo por uma area de armazenamento abstrata feita por thread de fluxo de dados. Por meio delas, \xc3\xa9 poss\xc3\xadvel realizar a execu\xc3\xa7\xc3\xa3o de sequencias, express\xc3\xb5es e realizar o bloqueio quando ocorre a indisponibilidade de dados na \xc3\xa1rea de restri\xc3\xa7\xc3\xb5es._NEWLINE_Sua \xc3\xa1rea de armazenamento \xc3\xa9 composto por 3 componentes: a \xc3\xa1rea de restri\xc3\xa7\xc3\xb5es, com as vari\xc3\xa1veis e valores instanciados, \xc3\xa1rea de procedimentos, com as defini\xc3\xa7\xc3\xb5es dos procedimentos e a \xc3\xa1rea das c\xc3\xa9lulas', com os apontadores mut\xc3\xa1veis._NEWLINE_A implementa\xc3\xa7\xc3\xa3o da linguagem \xc3\xa9 realizada num ambiente de desenvolvimento chamado de OPI (Oz_NEWLINE_Programming Interface). Este ambiente de desenvolvimento usa o Emacs, expandindo os seus menus e colora\xc3\xa7\xc3\xa3o sint\xc3\xa1ctica, de forma a facilitarem a programa\xc3\xa7\xc3\xa3o.\n_START_SECTION_\nProgramando em OZ\n_START_PARAGRAPH_\nA  melhor forma de iniciar a programa\xc3\xa7\xc3\xa3o \xc3\xa9 come\xc3\xa7ando pela sequencial, levando-se em considera\xc3\xa7\xc3\xa3o que um conjunto de instru\xc3\xa7\xc3\xb5es podem ser executadas sequencialmente (thread)._NEWLINE_As vari\xc3\xa1veis em OZ s\xc3\xa3o vari\xc3\xa1veis logicas, ou seja, s\xc3\xb3 podem ser instanciadas uma vez. este tipo de vari\xc3\xa1veis \xc3\xa9 usada em linguagens logicas, como prolog.\n_START_SECTION_\nFun\xc3\xa7\xc3\xb5es\n_START_PARAGRAPH_\nFun\xc3\xa7\xc3\xb5es s\xc3\xa3o valores de primeira classe, permitindo a programa\xc3\xa7\xc3\xa3o de ordem superior funcional:_NEWLINE_fun {Fact N}_NEWLINE_   if N =< 0 then 1 else N*{Fact N-1} end_NEWLINE_end_NEWLINE__NEWLINE_fun {Comb N K}_NEWLINE_   {Fact N} div ({Fact K} * {Fact N-K})\xc2\xa0% N\xc3\xa3o existe estouro de inteiros em Oz (a n\xc3\xa3o ser que n\xc3\xa3o haja mem\xc3\xb3ria sobrando)_NEWLINE_end_NEWLINE__NEWLINE_fun {SumList List}_NEWLINE_   case List of nil then 0_NEWLINE_   [] H|T then H+{SumList T}_NEWLINE_   end_NEWLINE_end\n_START_SECTION_\nVari\xc3\xa1veis \xe2\x80\x8b\xe2\x80\x8bde fluxo de dados e simultaneidade declarativa\n_START_PARAGRAPH_\nQuando o programa encontra uma vari\xc3\xa1vel unbound (fora dos limites) ele espera por um valor:_NEWLINE_thread_NEWLINE_   Z = X+Y     % ir\xc3\xa1 esperar at\xc3\xa9 que ambos X e Y s\xc3\xa3o ligados a um valor._NEWLINE_   {Browse Z}  % Mostra o valor de Z._NEWLINE_end_NEWLINE_thread X = 40 end_NEWLINE_thread Y = 2 end_NEWLINE_N\xc3\xa3o \xc3\xa9 poss\xc3\xadvel alterar o valor de uma vari\xc3\xa1vel de fluxo de dados, uma vez que \xc3\xa9 ligada:_NEWLINE_X = 1_NEWLINE_X = 2\xc2\xa0% erro_NEWLINE_Vari\xc3\xa1veis \xe2\x80\x8b\xe2\x80\x8bde fluxo de dados tornam mais f\xc3\xa1cil a cria\xc3\xa7\xc3\xa3o de agentes de fluxo concorrentes:_NEWLINE_fun {Ints N Max}_NEWLINE_   if N == Max then nil_NEWLINE_   else_NEWLINE_      {Delay 1000}_NEWLINE_      N|{Ints N+1 Max}_NEWLINE_   end_NEWLINE_end_NEWLINE__NEWLINE_fun {Sum S Stream}_NEWLINE_   case Stream of nil then S_NEWLINE_   [] H|T then S|{Sum H+S T} end_NEWLINE_end_NEWLINE__NEWLINE_local X Y in_NEWLINE_   thread X = {Ints 0 1000} end_NEWLINE_   thread Y = {Sum 0 X} end_NEWLINE_   {Browse Y}_NEWLINE_end_NEWLINE_Devido \xc3\xa0 maneira como as vari\xc3\xa1veis \xe2\x80\x8b\xe2\x80\x8bde fluxo de dados funciona, \xc3\xa9 poss\xc3\xadvel colocar threads em qualquer parte do programa e garante-se que ele ter\xc3\xa1 o mesmo resultado. Isto faz com que a programa\xc3\xa7\xc3\xa3o concorrente seja muito f\xc3\xa1cil. Threads s\xc3\xa3o muito baratas: \xc3\xa9 poss\xc3\xadvel ter centenas de milhares de threads em execu\xc3\xa7\xc3\xa3o de uma s\xc3\xb3 vez.\n_START_SECTION_\nOutro Exemplo\n_START_PARAGRAPH_\nEsse exemplo calcula um fluxo de n\xc3\xbameros primos usando o algoritmo Trial division, atrav\xc3\xa9s da cria\xc3\xa7\xc3\xa3o recursiva de agentes concorrentes de fluxo que filtram n\xc3\xbameros n\xc3\xa3o primos:_NEWLINE_fun {Sieve Xs}_NEWLINE_   case Xs of nil then nil_NEWLINE_   [] X|Xr then Ys in_NEWLINE_      thread Ys = {Filter Xr fun {$ Y} Y mod X \\= 0 end} end_NEWLINE_      X|{Sieve Ys}_NEWLINE_   end_NEWLINE_end\n_START_SECTION_\nLaziness\n_START_PARAGRAPH_\nOz faz uso de eager evaluation por padr\xc3\xa3o, mas lazy evaluation tamb\xc3\xa9m \xc3\xa9 poss\xc3\xadvel:_NEWLINE_fun lazy {Fact N}_NEWLINE_   if N =< 0 then 1 else N*{Fact N-1} end_NEWLINE_end_NEWLINE_local X Y in_NEWLINE_  X = {Fact 100}_NEWLINE_  Y = X + 1\xc2\xa0% the value of X is needed and fact is computed_NEWLINE_end\n_START_SECTION_\nSimultaneidade de passagem de mensagens\n_START_PARAGRAPH_\nO modelo declarativo concorrente pode ser estendido com a passagem de mensagens atrav\xc3\xa9s da sem\xc3\xa2ntica simples:_NEWLINE_declare_NEWLINE_local Stream Port in_NEWLINE_   Port = {NewPort Stream}_NEWLINE_   {Send Port 1}\xc2\xa0% Stream is now 1|_ ('_' indicates an unbound and unnamed variable)_NEWLINE_   {Send Port 2}\xc2\xa0% Stream is now 1|2|__NEWLINE_   ..._NEWLINE_   {Send Port n}\xc2\xa0% Stream is now 1|2| .. |n|__NEWLINE_end_NEWLINE_Com uma porta e uma thread o programador pode definir agentes ass\xc3\xadncronos:_NEWLINE_fun {NewAgent Init Fun}_NEWLINE_   Msg Out in_NEWLINE_   thread {FoldL Msg Fun Init Out} end_NEWLINE_   {NewPort Msg}_NEWLINE_end\n_START_SECTION_\nEstado e objetos\n_START_PARAGRAPH_\n\xc3\x89 novamente poss\xc3\xadvel estender o modelo declarativo para o apoiar programa\xc3\xa7\xc3\xa3o orientada a objetos e a estado com uma sem\xc3\xa2ntica muito simples; n\xc3\xb3s criamos uma nova estrutura de dados mut\xc3\xa1vel chamada Cells:_NEWLINE_local A X in_NEWLINE_   A = {NewCell 0}_NEWLINE_   A\xc2\xa0:= 1  % changes the value of A to 1_NEWLINE_   X = @A  % @ is used to access the value of A_NEWLINE_end_NEWLINE_Com essas simples mudan\xc3\xa7as de sem\xc3\xa2ntica, podemos apoiar o paradigma orientado a objetos._NEWLINE_Com um pouco de a\xc3\xa7\xc3\xbacar sint\xc3\xa1tico (syntactic sugar) a programa\xc3\xa7\xc3\xa3o orientada a objetos torna-se bem integrada em Oz._NEWLINE_class Counter_NEWLINE_   attr val_NEWLINE_   meth init(Value)_NEWLINE_      val:=Value_NEWLINE_   end_NEWLINE_   meth browse_NEWLINE_      {Browse @val}_NEWLINE_   end_NEWLINE_   meth inc(Value)_NEWLINE_      val\xc2\xa0:=@val+Value_NEWLINE_   end_NEWLINE_end_NEWLINE__NEWLINE_local C in_NEWLINE_   C = {New Counter init(0)}_NEWLINE_   {C inc(6)}_NEWLINE_   {C browse}_NEWLINE_end\n_START_SECTION_\nVelocidade de Execu\xc3\xa7\xc3\xa3o\n_START_PARAGRAPH_\nA velocidade de execu\xc3\xa7\xc3\xa3o de um programa produzido pelo compilador Mozart (vers\xc3\xa3o 1.4.0 implementando Oz 3) \xc3\xa9 muito lenta. Em um benchmark(teste de desempenho) \xc3\xa9 na m\xc3\xa9dia cerca de 50 vezes mais lento do que o compilador GCC para a linguagem C, resolvendo as tarefas de benchmark."