Mutumwa defends Johanne Masowe
Bulawayo based Johanne Masowe Echishanu leader Madzibaba Emmanuel ‘SG’ Mutumwa has condemned elements inside and outside the sect, who are tarnishing the image of the church.
Mutumwa said there are people who are plotting to divide the church through spreading lies about senior members.
He said he is the brand ambassador of the apostolic sect and is prepared to defend the gospel through ‘whatever means’.
“The truth shall set people free; people should follow what God is saying.
Related Articles
Goblins terrorise Makokoba residents
Nov 20, 2018 44,113 55
Nov 18, 2018 20,187 284
‘I started prophesying at the age of 8’. . .Madzibaba…
Nov 18, 2018 39,657 616
Satanist causes stir at church service
Oct 5, 2018 30,231 102
“Don’t tarnish mazita evanhu vasina mhaka, vari kuita zvakaipa vachangotongwa naMwari asi vazhinji vedu tiri kuita zvakanaka.

“I have told people about the true gospel, we are following the doctrine of the true gospel of baba Johanne.”
“People should prophesy using mweya waMwari, i beg people of Zimbabwe not follow social media, God is there and miracles exist.

Added Mutumwa:
“I feel pity for leaders who are fighting in church, they should correct their wrong doings.
“It’s my prayer that dai vanhu vemuHarare vese vemasowe nevasiri, vawanirwa nyasha dzekupihwa vanhu vaMwari vechokwadi.
“Ko mweya wehumbavha huri kubvepi, ngavatsvagewo zvekutengesa, zvakaita semaputi, majiggies kuti vavawanewo kurarama.
“They should stop fighting on social media tarnishing the image yeechurch yababa Johanne, ngavatsiurane pachavo.”
Mutumwa said people, who are causing divisions, should stop.
Related Stories:
“People who are causing divisions in church should correct themselves.
“Vana veJohanne Masowe should continue to pray because social media inopesanisa.
“People are fighting in church.
“Leaders who are fighting on social media, we condemn that, people should be vana vaMwari.
“They should return to order muchurch.
“Innocent people are being implicated in this fight, but they should correct each other,” he said.
He added:
“We don’t want such in our church and I am there to protect my church.
“I am supporting prophets who raise the name of the church.
“People should not spread zvinhu zvisina basa vachiuraya zita rechurch.
“Vana veZimbabwe should believe in prophets they trust.
“People should unite in church.
“Johanne Masowe is a good church ine vanhu vanotya Mwari.
“So people who are tarnishing our church on social media, vari kutisvibisira vanhu vakanaka.
“Church yechipotsori ichurch yakanaka chaizvo.
“Church should be protected, people are getting help from our church.” H-Metro


ALIEN 3 A film review by Serdar Yegulalp Copyright 1997 Serdar Yegulalp
CAPSULE: The weakest and least engaging of the Alien movies, dragged down by an uninvolving story and no real tension.
ALIEN 3 (the "3" should be in superscript) is a sad and wan entry in what was shaping up as one of the best SF sagas ever put on screen. It continues the story of Ripley, the space-trucker-turned-impromptu-survivalist, but seems remarkably uninterested in her. In fact, the movie seems lucky to be interested in anything at all, it's so elegaic and limp. A little of this would have been nice for atmosphere, but the movie telegraphs its own tragedy from the beginning.
At the end of the last film (ALIENS), Ripley and two survivors were on their way home. Unfortunately, an alien pod had been deposited in their ship, and wound up triggering off their ejection in an escape pod. The pod crashes on Firorina 161, a prison planet designed to house the incurably criminally violent. Ripley lives through the crash; the others do not.
The prison is a grim place, even as prisons go -- it's been built around the remnants of an abandoned steelworks, which provides no end of techno-gothic backdrops for the actors to be backlit against. Lice are endemic, and so Ripley's head is shaved (another surreal touch). At first it looks like she just has to hold out as an unwelcome guest until a Company rescue ship can arrive, but it doesn't stay that way. One of the other eggs on board the wrecked escape pod hatches, and soon a newly-gestated alien is running amuck. Worse, it looks like Ripley herself has been impregnated.
What's weird is how little tension this generates, except near the end, when the pressure is being troweled on through every cheap cinematic form of cheating imaginable: loud music, shaky camerawork, etc. Sigourney Weaver has become comfortable with the role, and she does well with it, but this time the role has been underwritten and left slack. The supporting actors are also not given a lot to do: the doctor (Charles Dance) and another, rather religious inmate (Charles S. Dutton, very good), hiave presence, but they're not asked to do anything with it.
In light of the impending sequel, which apparently plays fast and loose with the ending of this movie, I will not talk about the ending -- except to say that they found a remarkably good ending for such a drab movie. It's strange that some of the desperate and improvisational thinking that they found to wind up this story couldn't have driven the rest of it.
One and a half out of four dog-bursters.
<EMAIL_ADDRESS>EFNet IRC: GinRei http://www.io.com/~syegul another worldly device... UNMUTUAL: A Digital Art Collective - E-mail<EMAIL_ADDRESS>for details
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


What Is a Black Hole?
 The gravity is so strong because matter has been squeezed into a tiny space. This can happen when a star is dying. Because no light can get out, people can't see black holes. They are invisible. Space telescopes with special tools can help find black holes. The special tools can see how stars that are very close to black holes act differently than other stars.
A black hole can not be seen because strong gravity pulls all of the light into the middle of the black hole. But scientists can see how the strong gravity affects the stars and gas around the black hole. Scientists can study stars to find out if they are flying around, or orbiting, a black hole. When a black hole and a star are close together, high-energy light is made. This kind of light can not be seen with human eyes. Scientists use satellites and telescopes in space to see the high-energy light..
- uno
- dos
- tres
- uno
- dos
- tres


is a dynamic and exciting team building activity for anyone of any age or ability. Rapidly growing in popularity worldwide, this fun and motivating sport relies on everyone in the boat to work together toward a common goal,
DragonFire is a team building company specializing in Dragon Boat team building events for corporate clients.
For those unfamiliar with the sport, Dragon Boating simply put, is a boat of 20 paddlers, a drummer and a steers person paddling to cross the finish line faster than their competition.
It’s a fun, safe and inclusive activity ideal for clients looking for new and unique team building ideas.
The corporate world shares many similarities with Dragon Boating. Working together is the key to success in both arenas. Both rely on cooperation, communication and commitment to achieve high levels of productivity.
The dragon boat experience fosters a strong sense of camaraderie and accomplishment among participants. Best of all, everyone comes away enthusiastic and energized with a renewed sense of common purpose. Dragon Boating epitomizes the very essence of working as a team.
"'Love what you do, and do what you love!"
And so, the idea for DragonFire was born.
With twenty years combined experience, we pride ourselves in training hard, pushing the limits & together we, ‘race to win.’
As long term members of a highly competitive Dragon Boat Team, a healthy dose of competitiveness & our passion for Dragon Boating has helped claim a number of significant titles both locally & internationally, including the UAE Women’s Club Championship 2014 and a 3rd place win at the Hong Kong International Dragon Boat Races in 2013.
We draw on our expertise & knowledge to motivate our Corporate Clients through our Team Building Events.
The opportunity for an exciting challenge, coupled with a strong sense of teamwork enables participants to experience success & pride both in the boat & back in the workplace.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur et mi at libero gravida elementum nec vel
nibh. Ut vehicula neque eget nunc pulvinar, vitae aliquet ex tristique. Nulla facilisi. Donec eu mauris et nulla
rhoncus fermentum et at ante. Proin posuere vitae ipsum vel mattis. Donec semper consectetur lectus nec
viverra. Suspendisse maximus porta dolor, at consectetur orci faucibus ac. Morbi quis justo et diam rutrum
fermentum. Morbi facilisis quis odio eu placerat. Integer tempus ligula quis felis luctus, sit amet vestibulum
magna sodales. Proin sagittis odio volutpat lectus rhoncus, nec iaculis quam feugiat. Nunc sollicitudin felis
ipsum, eget bibendum turpis feugiat sit amet. Sed ultrices elementum libero vel tempus. Sed vitae gravida nisl.
Aliquam feugiat ex eget fermentum scelerisque. Integer nec porta mi. Pellentesque suscipit sem nibh, sit amet
sollicitudin diam fermentum eget. Mauris quis tempor orci. In commodo ipsum orci, ac commodo urna elementum
sed. Aenean non luctus nisl, pretium bibendum quam. Curabitur luctus dignissim urna non
maximus. Fusce semper nulla sed dolor vehicula, quis dapibus odio consectetur. Cras viverra ultricies
accumsan. Quisque quis lectus magna. Maecenas vel dolor iaculis, blandit lectus et, rutrum sem.
Etiam dignissim semper semper. Vivamus tempus aliquet ligula, quis imperdiet libero venenatis sed.
Pellentesque aliquet justo at ex condimentum ullamcorper. Quisque ut urna tempor, varius nisi vitae,
vestibulum dui. Nulla leo turpis, iaculis id sapien non, consequat faucibus dui.
Call
+971526994788
+971507355498
<EMAIL_ADDRESS>DragonFire operates at the beautiful Sheraton Jumeirah
Beach Resort in Dubai and holds all events
exclusively
at this venue.
As part of the team building package, clients select from a
variety of food and beverage options available.


Enable regenerative braking
When this is enabled, pushing brake handles will activate regenerative braking.
Braking strength is binary (not dependant on how hard you press the brakes) and is configured by the parameter below.


{% extends "base.html" %} {% block title %} Good bye {% endblock %} {% block content %} You have left this group Your friends will miss you {% endblock %}


Gator Lost and Found
Home
(current)
Lost Items
Found Items
Report
Report Something Lost
Report Something Found
Something else here
{% include 'sidebar.html' %} {% block main %} {% endblock %}


How mediation works
The mediation service will contact you and Mary Richards to arrange an appointment with a mediator.
You'll talk to the mediator one-on-one - you won't talk to Mary Richards directly. The mediator might need to speak to you more than once, but the process won't last more than an hour.
The mediator will ask you both to:
- summarise the claim to help uncover underlying problems
- consider the claim from both sides
- be flexible
If mediation is successful you'll be asked to sign an agreement to formalise the settlement. If anyone breaks the terms of the agreement the case will go to court.
Go back


Archive for posts tagged with 'XSLT'
-
Manipulate XSLTsearch
When developing websites with Umbraco, I always use the XSLTsearch package to handle the search solution. As well as being easy and quick to install, it is customisable and very fast in searching content nodes. As much as I love XSLTsearch, the one dilemma I always face is having to modify the HTML output that is generated. Given the way I work; with a much better front-end developer providing the mark-up; I am faced with…
-
How to use umbraco.library GetMedia in XSLT for Umbraco v4.5
This is a quick follow-up on my previous blog post: “How to use umbraco.library GetMedia in XSLT“. At the request of fellow Umbraco South-West UK developer, Dan, that I should update the code snippets for the new XML schema in Umbraco v4.5+ First a quick notice; if you are using v4.5.0, then please upgrade to v4.5.1, as there was a tiny bug in GetMedia that caused great confusion and headaches – you have been advised!…
-
Working with XSLT using new XML schema in Umbraco 4.1
Most of the Umbraco community are aware that the XML schema in the upcoming Umbraco 4.1 release has changed. Instead of each document being a node element, the element name is the node-type alias, same with property values; they no longer use data elements with alias attributes. Here is a quick example, comparing the old/legacy with the new: <node id="1066" parentID="-1" level="1" nodeName="Home" ... nodeTypeAlias="Homepage" path="-1,1066"> <data alias="bodyText"><![CDATA[
Welcome to my homepage.
]]></data> </node> <Homepage id="1066" parentID="-1" level="1"…
-
How to use umbraco.library GetMedia in XSLT
From time to time I notice a reoccurring post over at the Our Umbraco forum; how to display an image (from the Media section) in XSLT? A quick answer can be found on the Our Umbraco wiki for the umbraco.library GetMedia method. For most uses, the last example in the wiki works great. But I want to show you a “super safe” way of dealing with GetMedia in XSLT. Where I find a lot of…
-
Umbraco: Ultimate Picker XSLT Example
Chatting with Dan (my partner-in-code at Bodenko) about the Ultimate Picker data-type in Umbraco, we realised that we couldn’t find any examples of how to use the data in XSLT. So obviously needing an excuse to write-up a new blog post, here we go. If you need a quick overview about the Ultimate Picker data-type, see Tim Geyssens’ blog post. For my example, using a default Umbraco install (with Runway), we will create a new…


Please enable JavaScript to navigate.
This page is auto-generated and does
not
contain any form of telemetry or ads.
JavaScript is required to navigate through header and to list blogs.
Complete source code for this site can be found at
https://github.com/AmithaLingala/Blog
.


This class is the glue that binds all of the Open Web Presence functionality together.
It acts as the controller, logic, and view handler without extreme complexity of an entire MVC framework.
Methods
Constructor
__construct()
| method |
|
| access |
public |
| global |
string $root_path The app root file path. |
| global |
string $current_web_root The current web root. |
| global |
object $PhpConsole PhpConsole debugger object. |
| uses |
|
| author |
Brian Tafoya |
| version |
1.0 |
action() Triggers the framework logic.
action()
processAction()
processAction(string $action)
| method |
Process the framework action. |
| access |
public |
| author |
Brian Tafoya |
| version |
1.0 |
Parameters
$action
string
Exceptions
\Exception |
Include does not exist. |
checkActionPermissions()
checkActionPermissions($action) : boolean
Parameters
$action
Returns
boolean
getActionData()
getActionData($action) : mixed
Parameters
$action
Returns
mixed
Properties
Object holder for dynamically loaded classes
$LoadedClasses : array
Phpconsole object
$PhpConsole : object
The app theme
$THEME : string
Theme specific actions configuration
$actionsConfig : object
Action finally processed after permissions are verified
$actualAction : string
The current web root
$current_web_root : string
Database object
$ezSqlDB : object
Framework object
$frameworkObject : object
The user action requested
$requested_action : string
The app root path
$root_path : string
The user object
$userClass : object
The request's uuid
$uuid : string


|
kpn-senml-C++
1.0.0
generate and parse senml data from json or cbor
|
#include <senml_record.h>
Public Member Functions | |
| SenMLRecord () | |
| SenMLRecord (const char *name) | |
| SenMLRecord (const char *name, SenMLUnit unit) | |
| double | getTime () |
| bool | setTime (double value, bool absolute=true) |
| const char * | getName () |
| void | setName (const char *name) |
| int | getUpdateTime () |
| bool | setUpdateTime (double value, bool absolute=true) |
| SenMLUnit | getUnit () |
| void | setUnit (SenMLUnit value) |
| virtual void | fieldsToJson () |
| virtual int | fieldsToCbor () |
| Public Member Functions inherited from SenMLBase | |
| SenMLBase * | getNext () |
| SenMLBase * | getRoot () |
Protected Member Functions | |
| virtual void | contentToJson () |
| virtual int | contentToCbor () |
| virtual void | adjustToBaseTime (double prev, double time) |
| virtual void | actuate (const void *value, int dataLength, SenMLDataType dataType) |
| int | getFieldLength () |
| Protected Member Functions inherited from SenMLBase | |
| void | setNext (SenMLBase *value) |
| void | setPrev (SenMLBase *value) |
| SenMLBase * | getPrev () |
| virtual bool | isPack () |
| virtual int | getArrayLength () |
Friends | |
| class | SenMLCborParser |
| class | SenMLJsonListener |
SenMLRecord represents a single measurement. Besides the value, it also stores the name, optional unit, timestamp and update time.
This is the base class for all record types, you can not work directly with this class. Instead, use one of it's derivatives such as SenMLBinaryRecord, SenMLBoolRecord, SenMLFloatRecord, SenMLIntRecord or SenMLStringRecord. Alternatively, you can create your own records by inheriting from this class, or SenMLRecordTemplate, a convenience template which allows you to create records for different data types.
Although a record object can be used by itself, usually record objects are added to SenMLPack objects.
|
inline |
create a SenMLRecord object.
| SenMLRecord::SenMLRecord | ( | const char * | name | ) |
create a SenMLRecord object.
| name | the identifier for this record. This is a free-form string, but a set of predefined names, supported by the KPN network can be found in senml_enums.h |
| SenMLRecord::SenMLRecord | ( | const char * | name, |
| SenMLUnit | unit | ||
| ) |
create a SenMLRecord object.
| name | the string that will be prepended to all records in this pack. Is used to represent the name of the device. |
| unit | the unit that should be included in the output. See the SenMLUnit enum for supported unit types. |
|
virtual |
renders all the fields to cbor format. renders all the fields of the object without the length info at the beginning note: this is public so that custom implementations for the record object can use other objects internally and render to json using this function (ex: coordinatesRecord using 3 floatRecrods for lat, lon & alt.
Implements SenMLBase.
Reimplemented in SenMLBinaryRecord, SenMLBoolRecord, SenMLFloatRecord, SenMLIntRecord, and SenMLStringRecord.
|
virtual |
renders all the fields to json, without the starting and ending brackets. Inheriters can extend this function if they want to add extra fields to the json output note: this is public so that custom implementations for the record object can use other objects internally and render to json using this function (ex: coordinatesRecord using 3 floatRecrods for lat, lon & alt.
Implements SenMLBase.
Reimplemented in SenMLBinaryRecord, SenMLBoolRecord, SenMLFloatRecord, SenMLIntRecord, and SenMLStringRecord.
|
inline |
Get the name of the record.
|
inline |
returns the time assigned to this record. NaN represents 'no time assigned'. See base fields for more info on the time value.
|
inline |
Get the enum that identifies the unit name assigned to the record. The value SENML_UNIT_NONE means that no unit will be generated in the output. Senml defines a fixed set of supported unit names.
|
inline |
Get the expected timestamp at which this record will be updated again. NaN represents 'no time assigned'.
|
inline |
Assign an identifier to the record. This is a free-form string, but a set of predefined names, supported by the KPN network can be found in senml_enums.h
| name | a string that represents the identifier for the record. A copy of the value is made. |
| bool SenMLRecord::setTime | ( | double | value, |
| bool | absolute = true |
||
| ) |
set the time, expressed as a unix epoch time, absolute or relative to the base time of the parent SenMLPack object.. when absolute is true (default behaviour), the time value will be made relative to the base time of the pack object, if it has a base time. See base fields for more info on the time value. Possible reasons for failure:
| value | the unix epoch time value to assign to the record |
| absolute | When true (default), the value will be interpreted as an absolute time stamp. If there is a parent SenMLPack, the value will be made relative to the pack's base time, if there is any. When false, no conversion is done, but a parent SenMLPack has to be present. |
|
inline |
Assigns a unit value to the record. The value SENML_UNIT_NONE means that no unit will be generated in the output. Senml defines a fixed set of supported unit names.
| value | a SenMLUnit enum value representing the unit name. |
| bool SenMLRecord::setUpdateTime | ( | double | value, |
| bool | absolute = true |
||
| ) |
Assign a timestamp to the record at which it is expected to update the value. when absolute is true (default behaviour), the time value will be made relative to the base time of the pack object, if it has a base time. See base fields for more info on the time value. Possible reasons for failure:
| value | the unix epoch update time value to assign to the record |
| absolute | When true (default), the value will be interpreted as an absolute time stamp. If there is a parent SenMLPack, the value will be made relative to the pack's base time, if there is any. When false, no conversion is done, but a parent SenMLPack has to be present. |


From:Scott Neal To:Daniel Reck; Kimberly Brown Sent:2017-01-11T04:45:25.0000000Z Subject:Re: Associate PRC
John Massey
Daniel Reck
06/30/2000 07:49 AM
To: Kimberly Brown/HOU/ECT@ECT
cc: Scott Neal/HOU/ECT@ECT
Subject: Re: Associate PRC
Any idea which associate he might be representing?
--Dan
Enron North America Corp.
From: Scott Neal 06/29/2000 12:32 PM
Sent by: Kimberly Brown
To: Scott Neal/HOU/ECT@ECT
cc: (bcc: Daniel Reck/HOU/ECT)
Subject: Associate PRC
Scott Neal will be represting an associate in your group. Please forward
feedback to him no later than July 7.
Many Thanks
If you have more than one associate please contact Kimberly Brown x35193.
***********
EDRM Enron Email Data Set has been produced in EML, PST and NSF format by ZL Technologies, Inc. This Data Set is licensed under a Creative Commons Attribution 3.0 United States License <http://creativecommons.org/licenses/by/3.0/us/> . To provide attribution, please cite to "ZL Technologies, Inc. (http://www.zlti.com)."
***********
California


{{event.author.full_name}} updated the status of the task "{{ event.event_info.task_title }}" from to on


Before Change
assert_almost_equal(T(d), 1.0)
def test_tc2():
outcomes = ["0000", "0011", "0101", "0110",
"1001", "1010", "1100", "1111"]
pmf = [1/8] * 8
d = D(outcomes, pmf)
assert_almost_equal(T(d), 1.0)
def test_tc3():
outcomes = ["0000", "0011", "0101", "0110",
After Change
def test_tc2():
Test T of subvariables, with names
d = n_mod_m(4, 2)
assert_almost_equal(T(d, [[0], [1], [2]]), 0.0)
d.set_rv_names("XYZW")
assert_almost_equal(T(d, [["X"], ["Y"], ["Z"]]), 0.0)


Cookie Consent module for Angular.
Scroll down to see it in action!
Learn More Documentation Edit on StackBlitz


pyez_config.rst¶
Begin by importing your method:
from nornir_pyez.plugins.tasks import pyez_config
2. Now you will need to decide which serialization that you want to send the data in with. ‘text’ is the default. Payload must be passed as a string A text payload example:
payload = """interfaces {
lo0 {
unit 0 {
family inet {
address <IP_ADDRESS>/32;
}
}
}
}
"""
Take notice of the XML payload’s ability to use attributes like operation=”replace” This will remove and replace this subtree of the candidate config. An XML payload example:
xml_payload = """
<configuration>
<interfaces>
<interface>
<name>lo0</name>
<unit>
<name>0</name>
<family operation="replace">
<inet>
<address>
<name><IP_ADDRESS>/32</name>
</address>
</inet>
</family>
</unit>
</interface>
</interfaces>
</configuration>
"""
Note JSON is also a valid payload with data_format=’json’ set
Next you need to decide if you want to commit the changes now, or create a new task to view the diff
Example of NO commit now:
send_result = task.run(
task=pyez_config, payload=xml_payload, data_format='xml')
Example of commit now:
send_result = task.run(
task=pyez_config, payload=xml_payload, data_format='xml', commit_now=True)
Full example:
from nornir_pyez.plugins.tasks import pyez_config
import os
from nornir import InitNornir
from rich import print
script_dir = os.path.dirname(os.path.realpath(__file__))
nr = InitNornir(config_file=f"{script_dir}/config.yml")
payload = """interfaces {
lo0 {
unit 0 {
family inet {
address <IP_ADDRESS>/32;
}
}
}
}
"""
response = nr.run(
task=pyez_config, payload=payload
)
# response is an AggregatedResult, which behaves like a list
# there is a response object for each device in inventory
devices = []
for dev in response:
print(response[dev].result)


raw information
germany model
germany - raw
germany - split
germany - overall
uk model
uk - raw
uk - split
uk - overall
us model
us - raw
us - split
us - overall
what's this?
remove bars
explore


Your Treatment: {{treatment.TreatmentID}} Back
| Ailment | {{treatment.TreatmentID}} |
|---|---|
| Doctor | {{treatment.DocID}} |
| Prescription Date | {{treatment.PrescriptionDate}} |
| Expected Outcome | {{treatment.ExpectedOutcome}} |
| Warnings | {{treatment.Warnings}} |
{% load static %}
| Ailment | {{treatment.TreatmentID}} |
|---|---|
| Doctor | {{treatment.DocID}} |
| Prescription Date | {{treatment.PrescriptionDate}} |
| Expected Outcome | {{treatment.ExpectedOutcome}} |
| Warnings | {{treatment.Warnings}} |


---
layout: post
title: Set plan for the Crimson Rivers
date: '2018-05-31T15:35:31+02:00'
categories:
- Storyboards
picture_url: https://film-Storyboards.tumblr.com/post/174444624771/set-plan-crimson-river
---
Set plan for the roof chase in La Croisade des Enfants, a Crimson Rivers TV series episode directed by Olivier Barma.


GLFW now supports basic integration with Vulkan with glfwVulkanSupported, glfwGetRequiredInstanceExtensions, glfwGetInstanceProcAddress, glfwGetPhysicalDevicePresentationSupport and glfwCreateWindowSurface. Vulkan header inclusion can be selected with GLFW_INCLUDE_VULKAN.
GLFW now supports switching between windowed and full screen modes and updating the monitor and desired resolution and refresh rate of full screen windows with glfwSetWindowMonitor.
GLFW now supports window maximization with glfwMaximizeWindow and the GLFW_MAXIMIZED window hint and attribute.
GLFW now supports giving windows input focus with glfwFocusWindow.
GLFW now supports setting both absolute and relative window size limits with glfwSetWindowSizeLimits and glfwSetWindowAspectRatio.
GLFW now supports querying the localized name of printable keys with glfwGetKeyName, either by key token or by scancode.
GLFW now supports waiting for events for a set amount of time with glfwWaitEventsTimeout.
GLFW now supports setting the icon of windows with glfwSetWindowIcon.
GLFW now supports raw timer values with glfwGetTimerValue and glfwGetTimerFrequency.
GLFW now supports notifying when a joystick has been connected or disconnected with glfwSetJoystickCallback.
GLFW now supports creating windows without a OpenGL or OpenGL ES context with GLFW_NO_API.
GLFW now supports selecting the context creation API at run-time with the GLFW_CONTEXT_CREATION_API window hint value.
GLFW now supports creating OpenGL and OpenGL ES contexts that do not emit errors with the GLFW_CONTEXT_NO_ERROR window hint, provided the machine supports the GL_KHR_no_error
extension.
GLFW now supports being used as a config-file package from other projects for easy linking with the library and its dependencies.
These are the release highlights. For a full list of changes see the version history.
GLFW now supports creating and setting both custom cursor images and standard cursor shapes. They are created with glfwCreateCursor or glfwCreateStandardCursor, set with glfwSetCursor and destroyed with glfwDestroyCursor.
GLFW now provides a callback for receiving the paths of files and directories dropped onto GLFW windows. The callback is set with glfwSetDropCallback.
GLFW now provides the glfwPostEmptyEvent function for posting an empty event from another thread to the main thread event queue, causing glfwWaitEvents to return.
GLFW now supports querying the size, on each side, of the frame around the client area of a window, with glfwGetWindowFrameSize.
GLFW now supports disabling auto-iconification of full screen windows with the GLFW_AUTO_ICONIFY window hint. This is intended for people building multi-monitor installations, where you need windows to stay in full screen despite losing input focus.
GLFW now supports floating windows, also called topmost or always on top, for easier debugging with the GLFW_FLOATING window hint.
GLFW now supports preventing a windowed mode window from gaining input focus on creation, with the GLFW_FOCUSED window hint.
GLFW now queries the window input focus, visibility and iconification attributes and the cursor position directly instead of returning cached data.
GLFW now provides a callback for character events with modifier key bits. The callback is set with glfwSetCharModsCallback. Unlike the regular character callback, this will report character events that will not result in a character being input, for example if the Control key is held down.
GLFW now supports the creation of single buffered windows, with the GLFW_DOUBLEBUFFER window hint.
GLFW now includes the extension header appropriate for the chosen OpenGL or OpenGL ES header when GLFW_INCLUDE_GLEXT is defined. GLFW does not provide these headers. They must be provided by your development environment or your OpenGL or OpenGL ES SDK.
GLFW now supports controlling whether the pipeline is flushed when a context is made non-current, with the GLFW_CONTEXT_RELEASE_BEHAVIOR window hint, provided the machine supports the GL_KHR_context_flush_control
extension.
GLFW now has an experimental Wayland display protocol backend that can be selected on Linux with a CMake option.
GLFW now has an experimental Mir display server backend that can be selected on Linux with a CMake option.
These are the release highlights. For a full list of changes see the version history.
GLFW now uses the CMake build system instead of the various makefiles and project files used by earlier versions. CMake is available for all platforms supported by GLFW, is present in most package systems and can generate makefiles and/or project files for most popular development environments.
For more information on how to use CMake, see the CMake manual.
GLFW now supports the creation of multiple windows, each with their own OpenGL or OpenGL ES context, and all window functions now take a window handle. Event callbacks are now per-window and are provided with the handle of the window that received the event. The glfwMakeContextCurrent function has been added to select which context is current on a given thread.
GLFW now explicitly supports multiple monitors. They can be enumerated with glfwGetMonitors, queried with glfwGetVideoModes, glfwGetMonitorPos, glfwGetMonitorName and glfwGetMonitorPhysicalSize, and specified at window creation to make the newly created window full screen on that specific monitor.
All string arguments to GLFW functions and all strings returned by GLFW now use the UTF-8 encoding. This includes the window title, error string, clipboard text, monitor and joystick names as well as the extension function arguments (as ASCII is a subset of UTF-8).
GLFW now supports reading and writing plain text to and from the system clipboard, with the glfwGetClipboardString and glfwSetClipboardString functions.
GLFW now supports setting and reading back the gamma ramp of monitors, with the glfwGetGammaRamp and glfwSetGammaRamp functions. There is also glfwSetGamma, which generates a ramp from a gamma value and then sets it.
GLFW now supports the creation of OpenGL ES contexts, by setting the GLFW_CLIENT_API
window hint to GLFW_OPENGL_ES_API
, where creation of such contexts are supported. Note that GLFW does not implement OpenGL ES, so your driver must provide support in a way usable by GLFW. Modern Nvidia and Intel drivers support creation of OpenGL ES context using the GLX and WGL APIs, while AMD provides an EGL implementation instead.
GLFW now has an experimental EGL context creation back end that can be selected through CMake options.
GLFW now supports high-DPI monitors on both Windows and OS X, giving windows full resolution framebuffers where other UI elements are scaled up. To achieve this, glfwGetFramebufferSize and glfwSetFramebufferSizeCallback have been added. These work with pixels, while the rest of the GLFW API works with screen coordinates. This is important as OpenGL uses pixels, not screen coordinates.
GLFW now has an error callback, which can provide your application with much more detailed diagnostics than was previously possible. The callback is passed an error code and a description string.
Each window now has a user-defined pointer, retrieved with glfwGetWindowUserPointer and set with glfwSetWindowUserPointer, to make it easier to integrate GLFW into C++ code.
Each window now has a callback for iconification and restoration events, which is set with glfwSetWindowIconifyCallback.
Each window now has a callback for position events, which is set with glfwSetWindowPosCallback.
The position of a window can now be retrieved using glfwGetWindowPos.
Each windows now has a callback for focus events, which is set with glfwSetWindowFocusCallback.
Each window now has a callback for when the mouse cursor enters or leaves its client area, which is set with glfwSetCursorEnterCallback.
The title of a window is now specified at creation time, as one of the arguments to glfwCreateWindow.
Windows can now be hidden with glfwHideWindow, shown using glfwShowWindow and created initially hidden with the GLFW_VISIBLE
window hint. This allows for off-screen rendering in a way compatible with most drivers, as well as moving a window to a specific position before showing it.
Windowed mode windows can now be created without decorations, e.g. things like a frame, a title bar, with the GLFW_DECORATED
window hint. This allows for the creation of things like splash screens.
Modifier key bit mask parameters have been added to the mouse button and key callbacks.
A scancode parameter has been added to the key callback. Keys that don't have a key token still get passed on with the key parameter set to GLFW_KEY_UNKNOWN
. These scancodes will vary between machines and are intended to be used for key bindings.
The name of a joystick can now be retrieved using glfwGetJoystickName.
You are reading it.
Last update on Thu Aug 18 2016 for GLFW 3.2.1


Research
Chaetognaths
These minute marine predators constitute one of the most enigmatic animal phyla. I started working with them during my PhD, attempting to resolve their phylogenetic position using genomic data. We showed that they exhibit a mixture of very original characters, both an morphological and genomic levels, that could be reminiscent of the bilaterian ancestor. I am now attempting to sequence and comparatively analyse their genome, but also to conduce some gene expression work to investigate their original embryology. I am also interested in their high polymorphism and its impact on genome regulation.
Collaborators
Katja Peijnenburg (Univ. Amsterdam), Yannick Le Parco (Université d'Aix-Marseille), Max Telford (UCL, IK), Noriyuki Satoh (OIST, Japan), Génoscope (CEA, France)


Home
Basic Info
Computers
Phones
Tablets
Beepers
Place of Death
Cause of Death
Decedent of Death
wizard content goes here


Pat's Salmon Cookies
to sales page
Locations
1st & Pike
SeaTac Airport
Seattle Center
Capitol Hill
Alki Beach
All location open 6am to 8pm
Call<PHONE_NUMBER> or stop by for more informnation!


Amazon Com Agptek U3 Usb Stick Mp3 Player 8gb Music Player Supports Replaceable Aaa Battery Recording Fm Radio Expandable Up To 128gb Black Electronics
Mp3 Player Mp3 Player With Aaa Battery Mp3 Music Player Audio Song Free Download Alibaba Com
Amazon Com Music Free Downloader Mp3 Songs Download Song For Free Appstore For Android
Single Aaa Bad Love Jpoplibs
Free Music Downloader Free Mp3 Downloader For Android Apk Download
Music Download Site Full Of Mp3 Downloads Music Videos Music Lyrics Music Download Music Xbox Live
Download Brymo A A A Ep Zip Mp3 Justnaija
Shinjiro Atae From Aaa California Dreaming のmp3フルダウンロードを無料で
3gp Mp3 Songs Free Download Mp3 Player With Aaa Battery Music Player Buy 3gp Mp3 Songs Free Download Mp3 Music Player Mp3 Player With Aaa Battery Product On Alibaba Com
Giesen Unisono 3 Singer Songwr Aaa Aaa Guitar Duo Malte Giesen Mp3 Downloads 7digital United States
Amazon Com Music Free Downloader Mp3 Songs Download Song For Free Appstore For Android
Amazon Com Talking Products Mp3 Recordable Sound Chip Module 4mb Memory With Aaa Battery Box Ideal For Models And Crafts Electronics
3gp Mp3 Songs Free Download Mp3 Player With Aaa Battery Music Player Buy 3gp Mp3 Songs Free Download Mp3 Music Player Mp3 Player With Aaa Battery Product On Alibaba Com
Echo Deep Drum Piano Dancemusic Housemusic Techno Techhouse Deephouse Afrohouse Afro Edm Songs Drums Deep
Amazon Com Sandisk Sansa M250 2 Gb Mp3 Player Black Home Audio Theater
Future Nights The Bunker New York 024 Atom The Bunker New York
Talking Hearts Mp3 Player Add Sound To Your Gifts And Keepsakes Talking Products Ltd
3gp Mp3 Songs Free Download Mp3 Player With Aaa Battery Music Player Buy 3gp Mp3 Songs Free Download Mp3 Music Player Mp3 Player With Aaa Battery Product On Alibaba Com
Download Mp3 Rayvanny Ccm Wayaaa New Song 042nobs
Free Music Downloader Free Mp3 Downloader For Android Apk Download
3gp Mp3 Songs Free Download Mp3 Player With Aaa Battery Music Player Buy 3gp Mp3 Songs Free Download Mp3 Music Player Mp3 Player With Aaa Battery Product On Alibaba Com
Polku Klava Eclipse Music Official Store
レコチョクから音楽を無料ダウンロードする方法2020年 Leawo 製品マニュアル
Download Aaa Mp3 Song Lyrics Aaa Online By Nyk Joox


Do Markov chain Monte Carlo (MCMC) simulation of Potts models (Potts, 1952, <https://doi.org/10.1017/S0305004100027419>), which are the multi-color generalization of Ising models (so, as as special case, also simulates Ising models). Use the Swendsen-Wang algorithm (Swendsen and Wang, 1987, <https://doi.org/10.1103/PhysRevLett.58.86>) so MCMC is fast. Do maximum composite likelihood estimation of parameters (Besag, 1975, <https://doi.org/10.2307/2987782>, Lindsay, 1988, <https://doi.org/10.1090/conm/080>).
| Version: | 0.5-7 |
| Depends: | R (≥ 3.0.2) |
| Imports: | stats, graphics, compiler |
| Suggests: | pooh (≥ 0.2) |
| Published: | 2017-03-16 |
| Author: | Charles J. Geyer and Leif Johnson |
| Maintainer: | Charles J. Geyer <charlie at stat.umn.edu> |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: | http://www.stat.umn.edu/geyer/mcmc/ |
| NeedsCompilation: | yes |
| Materials: | NEWS ChangeLog |
| CRAN checks: | potts results |
| Reference manual: | potts.pdf |
| Vignettes: |
CLL Crash Course |
| Package source: | potts_0.5-7.tar.gz |
| Windows binaries: | r-devel: potts_0.5-7.zip, r-release: potts_0.5-7.zip, r-oldrel: potts_0.5-7.zip |
| OS X binaries: | r-release: potts_0.5-7.tgz, r-oldrel: potts_0.5-7.tgz |
| Old sources: | potts archive |
Please use the canonical form https://CRAN.R-project.org/package=potts to link to this page.


The food name is {{ food.name }}
Two {{ food.name }} has {{ 2 * food.calories }} calories
One apple has {{ getFat() }} grams of fat


Search for academics who received awards by NSERC & SSHRC institutions using keywords found in their project summary.


ShopieStore
Home
Contact Us
About
Signup
Categories
Jeans
Shoes
Home Decor
Gym Wear
Jewellery
Toys
Kids wear
Tops
Books
Mobiles
Ripped Skinny Jeans
$24.99
Add to Cart
Vintage Skinny Jeans
$14.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Mega Ripped Jeans
$19.99
Add to Cart
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.


--- layout: map title: Stuttgart ---
Click on a marker below to begin investigating slavery in {{ page.title }}.


The course has concluded!
Thanks all for an interesting semester.
The final exam is here: finalexam.pdf
Hope everyone has an enlightening and fulfilling summer.
The course has concluded!
Thanks all for an interesting semester.
The final exam is here: finalexam.pdf
Hope everyone has an enlightening and fulfilling summer.
Slides from class: class27.pdf
Some solutions and hints on the practice final are here: practicefinal-comments.pdf. (If there are questions about problems with incomplete solutions, we might add to this later.)
We won’t have the regular office hours schedule now that the end of classes has passed, but still have many office hours scheduled until the final exam on May 11. Please check the course calendar (and discord announcements) for information on office hours for this week and next week.
As scheduled by the Registrar, the final exam will be Thursday, 11 May, 2:00pm - 5:00pm in our normal classroom.
The final exam will cover everything we’ve done in the course, but with more emphasis on material that has been covered since the midterm.
There is now a Classes page that lists all the classes to make it easier for you to find specific content we’ve covered in class.
Like the midterm, you may prepare a one-page (letter-size, two-sided) reference sheet for use during the exam, but all other resources are forbidden (no internet, textbook, other humans, magnification instruments, etc.). We expect that students will benefit from thinking about what to put on your reference sheet in preparing for the exam, and you may work with anyone you want (including other students in the class) to prepare your reference sheets together.
We have provided a practice final exam here: practicefinal.pdf
We will be posting solutions for these problems soon, but encourage you to try them yourself first under exam-like conditions.
Slides from class: class26.pdf
Problem Set 10 is due on Friday, 28 April. The latex template is https://www.overleaf.com/read/ppdjrxcwqmnn.
Slides from class: class25.pdf
Problem Set 10 is due on Friday, 28 April. The latex template is https://www.overleaf.com/read/ppdjrxcwqmnn.
Quiz 11 (which is a “make-up quiz”) is due 9:59pm on Wednesday, April 26.
Slides from class: class24.pdf
Problem Set 10 is due on Friday, 28 April. The latex template is https://www.overleaf.com/read/ppdjrxcwqmnn.
Slides from class: class23.pdf
Problem Set 10 is due on Friday, 28 April. The latex template is https://www.overleaf.com/read/ppdjrxcwqmnn.
Slides from class: class22.pdf
Problem Set 9 is due on Monday, 17 April. The latex template is https://www.overleaf.com/read/mqwmbzjppfbv.
Slides from class: class21.pdf
Problem Set 9 is due on Monday, 17 April. The latex template is https://www.overleaf.com/read/mqwmbzjppfbv.
If the key opening door reduction isn’t exciting enough for you (or you’re just a fan of 1980s TV shows), you may want to watch this video: Proof by Reduction (from Fall 2020 course).
Slides from class: class20.pdf
The learned video on computability from class is here.
If you want another presentation of the computability material in the textbook, try Dori-Mic and the Universal Machine!.
Problem Set 8 is due on Monday, 10 April. The latex template is https://www.overleaf.com/read/nhgcvwvnfvkh.


|
MDAL
|
The MemoryDataset stores all the data in the memory. More...
#include <mdal_memory_data_model.hpp>
Public Member Functions | |
| MemoryDataset2D (DatasetGroup *grp, bool hasActiveFlag=false) | |
| size_t | scalarData (size_t indexStart, size_t count, double *buffer) override |
| For DataOnVertices or DataOnFaces. | |
| size_t | vectorData (size_t indexStart, size_t count, double *buffer) override |
| For DataOnVertices or DataOnFaces. | |
| size_t | activeData (size_t indexStart, size_t count, int *buffer) override |
| Returns 0 for datasets that does not support active flags. | |
| void | activateFaces (MDAL::MemoryMesh *mesh) |
| Loop through all faces and activate those which has all 4 values on vertices valid Dataset must support active flags and be defined on vertices. | |
| void | setActive (size_t index, int stat) |
| Sets active flag for index. More... | |
| void | setActive (const int *activeBuffer) |
| int | active (size_t index) const |
| void | setScalarValue (size_t index, double value) |
| void | setVectorValue (size_t index, double x, double y) |
| void | setValueX (size_t index, double x) |
| void | setValueY (size_t index, double x) |
| double | valueX (size_t index) const |
| double | valueY (size_t index) const |
| double | scalarValue (size_t index) const |
| double * | values () |
| Returns pointer to internal buffer with values Never null, already allocated for vector datasets in form x1, y1, ..., xN, yN. | |
| Public Member Functions inherited from MDAL::Dataset2D | |
| Dataset2D (DatasetGroup *parent) | |
| size_t | verticalLevelCountData (size_t indexStart, size_t count, int *buffer) override |
| For DataOnVolumes. | |
| size_t | verticalLevelData (size_t indexStart, size_t count, double *buffer) override |
| For DataOnVolumes. | |
| size_t | faceToVolumeData (size_t indexStart, size_t count, int *buffer) override |
| For DataOnVolumes. | |
| size_t | scalarVolumesData (size_t indexStart, size_t count, double *buffer) override |
| For DataOnVolumes. | |
| size_t | vectorVolumesData (size_t indexStart, size_t count, double *buffer) override |
| For DataOnVolumes. | |
| size_t | volumesCount () const override |
| size_t | maximumVerticalLevelsCount () const override |
| Public Member Functions inherited from MDAL::Dataset | |
| Dataset (DatasetGroup *parent) | |
| size_t | valuesCount () const |
| Statistics | statistics () const |
| void | setStatistics (const Statistics &statistics) |
| bool | isValid () const |
| DatasetGroup * | group () const |
| Mesh * | mesh () const |
| double | time (RelativeTimestamp::Unit unit) const |
| RelativeTimestamp | timestamp () const |
| void | setTime (double time, RelativeTimestamp::Unit unit=RelativeTimestamp::hours) |
| void | setTime (const RelativeTimestamp &time) |
| bool | supportsActiveFlag () const |
| void | setSupportsActiveFlag (bool value) |
The MemoryDataset stores all the data in the memory.
|
inline |
Sets active flag for index.
| stat | 1 for active, 0 for non-active |
| index | index of the flag |
Dataset must support active flags


This example loads employees.xml and transforms it using employees2.xslt. The parameter message is passed in and is equal to "Hello World!". The resulting code is then displayed.
message


{% extends 'core/base.html' %} {% block content %}
Each month, part of the proceeds from Creator and Patron of the Arts subscriptions are added to the Loot. At the end of the month, the Loot is distributed to Creators and Patrons according to their Engagement Score.
| Event | Points |
|---|---|
| A subscribed user views your content | +100 |
| A subscribed user reverbs your content | +200 |
| A subscribed user comments on your content | +300 |
| A subscribed user replies to your comment | +300 |
| You are followed by a subscribed user | +500 |
When any of the above events occur, you receive the corresponding amount of points. At the end of the month, your score will be compared to the total score on Delta-Lyceum to determine your share of the loot. After you receive your share on Payday, your score is reset. Any new interactions with your content will be added to your score for the following month.


Simple Interest Calculator
Principal
Rate
Time in Months(Note: Intrest Rate are per annum)
Simple Intrest


Margin border and padding can be a bit confusing when first getting started in html. For me it was because they all have similar meanings. They all deal with the spacing surrounding and interior piece of code.
My first thought was to just memorize the order. For me looking at it from inside out seemed the best. Below is a simple diagram of how its layed out.
There’s one problem that I realized almost immediately when looking at it this way. And that is that it’s simple not enough. Even though you know the order, you really need to know how each one affects the layout of your page. I soon found out that all, some or none of these can be used. And depending on your page padding or margin elements might look the same and be interchangeable. Or they can make it completely different. So below I will try to explain each one in simple terms.
Padding:
If all of these terms describe the area around something then padding is the most inner area. I like to think of it as the space around the text being displayed. It’s probably more accurate to call it an inside border. But unlike a border. Padding is invisible, meaning you cannot change the color or style. Color is only affected by the background of the object. Below is an example of two boxes with text in them. The one on the left has no padding while they both have a a black border of 2px.
Border:
Border is directly surrounds your padding. Border can be used to create space between objects. And if it’s invisible it can give visually the same results as padding. But the border is more often used to visually separate objects. A border can be any color. It can also vary in whatever thickness you’d like. But thats not all, borders can be rounded by adjusting the radius. They can be created to provide a shadow property to the object. They can even consist of pictures.
Margin: Lastly we have margins. Margins are outside of the border and are used for spacing your objects. Like padding, margins are transparent. Margins are often automatically positioned by the browser. There are two common ways to specify these elements in css. First, you can individually write out the different sides as show on the left. Another write them in line. Your computer will always read from the top property first and go clockwise. If all dimensions are equal then you only have to write it once.


{% load static %}
Best Cars
About Us
Contact Us
{% if user.is_authenticated %}
{{ user.first_name }}({{ user.username }})
Logout
{% else %}
{% csrf_token %}
Login
Sign Up
{% endif %}
{% csrf_token %}
Enter the review content:
Did you purchase the car? (If yes, kindly fill the below information as well. If no, You can just submit the form.)
Select your car (model-make-year):
{% for car in cars %}
{{car.name}}-{{car.maker.name}}-{{ car.year|date:"Y" }}
{% endfor %}
Select your purchase date:
Submit Review


A secondary index, put simply, is a way to efficiently access records in a database (the primary) by means of some piece of information other than the usual (primary) key. In Berkeley DB, this index is simply another database whose keys are these pieces of information (the secondary keys), and whose data are the primary keys. Secondary indexes can be created manually by the application; there is no disadvantage, other than complexity, to doing so. However, when the secondary key can be mechanically derived from the primary key and datum that it points to, as is frequently the case, Berkeley DB can automatically and transparently manage secondary indexes.
As an example of how secondary indexes might be used, consider a database containing a list of students at a college, each of whom has a unique student ID number. A typical database would use the student ID number as the key; however, one might also reasonably want to be able to look up students by last name. To do this, one would construct a secondary index in which the secondary key was this last name.
In SQL, this would be done by executing something like the following:
CREATE TABLE students(student_id CHAR(4) NOT NULL, lastname CHAR(15), firstname CHAR(15), PRIMARY KEY(student_id)); CREATE INDEX lname ON students(lastname);
In Berkeley DB, this would work as follows (a Java API example is also available):
struct student_record { char student_id[4]; char last_name[15]; char first_name[15]; }; .... void second() { DB *dbp, *sdbp; int ret; /* Open/create primary */ if ((ret = db_create(&dbp, dbenv, 0)) != 0) handle_error(ret); if ((ret = dbp->open(dbp, NULL, "students.db", NULL, DB_BTREE, DB_CREATE, 0600)) != 0) handle_error(ret); /* * Open/create secondary. Note that it supports duplicate data * items, since last names might not be unique. */ if ((ret = db_create(&sdbp, dbenv, 0)) != 0) handle_error(ret); if ((ret = sdbp->set_flags(sdbp, DB_DUP | DB_DUPSORT)) != 0) handle_error(ret); if ((ret = sdbp->open(sdbp, NULL, "lastname.db", NULL, DB_BTREE, DB_CREATE, 0600)) != 0) handle_error(ret); /* Associate the secondary with the primary. */ if ((ret = dbp->associate(dbp, NULL, sdbp, getname, 0)) != 0) handle_error(ret); } /* * getname -- extracts a secondary key (the last name) from a primary * key/data pair */ int getname(DB *secondary, const DBT *pkey, const DBT *pdata, DBT *skey) { /* * Since the secondary key is a simple structure member of the * record, we don't have to do anything fancy to return it. If * we have composite keys that need to be constructed from the * record, rather than simply pointing into it, then the user's * function might need to allocate space and copy data. In * this case, the DB_DBT_APPMALLOC flag should be set in the * secondary key DBT. */ memset(skey, 0, sizeof(DBT)); skey->data = ((struct student_record *)pdata->data)->last_name; skey->size = sizeof(((struct student_record *)pdata->data)->last_name); return (0); }
From the application's perspective, putting things into the database works exactly as it does without a secondary index; one can simply insert records into the primary database. In SQL one would do the following:
INSERT INTO student VALUES ("WC42", "Churchill ", "Winston ");
and in Berkeley DB, one does:
struct student_record s; DBT data, key; memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); memset(&s, 0, sizeof(struct student_record)); key.data = "WC42"; key.size = 4; memcpy(&s.student_id, "WC42", sizeof(s.student_id)); memcpy(&s.last_name, "Churchill ", sizeof(s.last_name)); memcpy(&s.first_name, "Winston ", sizeof(s.first_name)); data.data = &s; data.size = sizeof(s); if ((ret = dbp->put(dbp, txn, &key, &data, 0)) != 0) handle_error(ret);
Internally, a record with secondary key "Churchill" is inserted into the secondary database (in addition to the insertion of "WC42" into the primary, of course).
Deletes are similar. The SQL clause:
DELETE FROM student WHERE (student_id = "WC42");
looks like:
DBT key; memset(&key, 0, sizeof(DBT)); key.data = "WC42"; key.size = 4; if ((ret = dbp->del(dbp, txn, &key, 0)) != 0) handle_error(ret);
Deletes can also be performed on the secondary index directly; a delete done this way will delete the "real" record in the primary as well. If the secondary supports duplicates and there are duplicate occurrences of the secondary key, then all records with that secondary key are removed from both the secondary index and the primary database. In SQL:
DELETE FROM lname WHERE (lastname = "Churchill ");
In Berkeley DB:
DBT skey; memset(&skey, 0, sizeof(DBT)); skey.data = "Churchill "; skey.size = 15; if ((ret = sdbp->del(sdbp, txn, &skey, 0)) != 0) handle_error(ret);
Gets on a secondary automatically return the primary datum. If DB->pget() or DBC->pget() is used in lieu of DB->get() or DBC->get(), the primary key is returned as well. Thus, the equivalent of:
SELECT * from lname WHERE (lastname = "Churchill ");
would be:
DBT data, pkey, skey; memset(&skey, 0, sizeof(DBT)); memset(&pkey, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); skey.data = "Churchill "; skey.size = 15; if ((ret = sdbp->pget(sdbp, txn, &skey, &pkey, &data, 0)) != 0) handle_error(ret); /* * Now pkey contains "WC42" and data contains Winston's record. */
To create a secondary index to a Berkeley DB database, open the database that is to become a secondary index normally, then pass it as the "secondary" argument to the DB->associate() method for some primary database.
After a DB->associate() call is made, the secondary indexes become alternate interfaces to the primary database. All updates to the primary will be automatically reflected in each secondary index that has been associated with it. All get operations using the DB->get() or DBC->get() methods on the secondary index return the primary datum associated with the specified (or otherwise current, in the case of cursor operations) secondary key. The DB->pget() and DBC->pget() methods also become usable; these behave just like DB->get() and DBC->get(), but return the primary key in addition to the primary datum, for those applications that need it as well.
Cursor get operations on a secondary index perform as expected; although the data returned will by default be those of the primary database, a position in the secondary index is maintained normally, and records will appear in the order determined by the secondary key and the comparison function or other structure of the secondary database.
Delete operations on a secondary index delete the item from the primary database and all relevant secondaries, including the current one.
Put operations of any kind are forbidden on secondary indexes, as there is no way to specify a primary key for a newly put item. Instead, the application should use the DB->put() or DBC->put() methods on the primary database.
Any number of secondary indexes may be associated with a given primary database, up to limitations on available memory and the number of open file descriptors.
Note that although Berkeley DB guarantees that updates made using any DB handle with an associated secondary will be reflected in the that secondary, associating each primary handle with all the appropriate secondaries is the responsibility of the application and is not enforced by Berkeley DB. It is generally unsafe, but not forbidden by Berkeley DB, to modify a database that has secondary indexes without having those indexes open and associated. Similarly, it is generally unsafe, but not forbidden, to modify a secondary index directly. Applications that violate these rules face the possibility of outdated or incorrect results if the secondary indexes are later used.
If a secondary index becomes outdated for any reason, it should be discarded using the DB->remove() method and a new one created using the DB->associate() method. If a secondary index is no longer needed, all of its handles should be closed using the DB->close() method, and then the database should be removed using a new database handle and the DB->remove() method.
Closing a primary database handle automatically dis-associates all secondary database handles associated with it.
An error return during a secondary update in CDS or DS (which requires an abort in TDS) may leave a secondary index inconsistent in CDS or DS. There are a few non-error returns:
In the case of any other error return during a
secondary update in CDS or DS, delete the secondary
indices, recreate them and set the DB_CREATE
flag
to the DB->associate
method. Some examples of error returns that need to be
handled this way are:
Note that DB_RUNRECOVERY
and
DB_PAGE_NOTFOUND
are fatal errors
which should never occur during normal use of CDS or DS.
If those errors are returned by Berkeley DB when running
without transactions, check the database integrity with
the DB->verify
method before rebuilding
the secondary indices.


class: center, middle # Fun & Games with Fix, Cofree, and Doobie! Rob Norris • `@tpolecat` • Gemini Observatory ??? - I'm Rob, I'm from Portland, first time in Montréal - For my day job I write software for big telescopes (in Scala) but I also work on some open-source projects in support of typeful, pure functional programming in Scala. That's what I'm interested in. If **you** are interested in this kind of programming I encourage you to get involved with Typelevel because that's what we're all about. - I would have put a typelevel logo on the slide but i don't understand css so i gave up. - If you don't mid admitting it, how many of you have used scalaz or cats? - So today I want to talk about some odds and ends that I think are interesting, and we'll see if you find them interesting too. --- # Goals 1. Gain an intuition about some simple recursive types. 2. Gain some confidence pushing on code to see what happens. 3. Learn how boring doobie is. 4. Do not panic. ??? 1. --- that's the main point of the talk. These types seem to be pretty well known in the Haskell community but not so much among Scala programmers, and they're interesting and worth knowing about. 2. --- so, this is something I mention from time to time when I give talks and people ask me to say more about it, so I'll try to do that as well. 3. --- Ok, so this is ostensibly a talk about database programming with doobie, which is a library I work on, but because it's a pure functional libary everything just kind of works so it's a very low-drama way to do things. 4. --- Recursion is always mind-blowing at first. Everybody struggles with recursive functions and self-referential data, and today we're going to talk about self-referential types, which may be new to a lot of you. So remain calm, this can be hard to grasp. So I'm going to try to approach it very gradually. If it ends up being too slow for you, I apologize; if it's too fast I also apologize. But please stop me if you have questions. Ok so let's look at a recursive data type. --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( name: String, year: Int, students: List[Prof] ) ```
??? - ... - So the kind of invented problem I want to talk about is how to store this in a relational database. So how do I save one of these tree structures to a database and read it back? --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( name: String, year: Int, students: List[Prof] ) ``` Natural SQL representation:
```sql CREATE TABLE prof ( id INTEGER IDENTITY, parent INTEGER NULL, name VARCHAR NOT NULL, year INTEGER NOT NULL, FOREIGN KEY(parent) REFERENCES prof(id) ) ``` ??? - Here's how you normally want to do it. - ... - You have the child refer to its parent, so the relationship is inverted. - But before we get to the parent-child relationship we need to talk about how we're going to represent the id on the Scala side. - Ok so here's one possibility. --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( id : Int @@ Prof, name: String, year: Int, students: List[Prof] ) ``` Natural SQL representation.
```sql CREATE TABLE prof ( id INTEGER IDENTITY, parent INTEGER NULL, name VARCHAR NOT NULL, year INTEGER NOT NULL, FOREIGN KEY(parent) REFERENCES prof(id) ) ``` ??? - ... - So we would probably use a tagged type or something to store this, but just for simplicity I'm going to use a plan `Int`. - Also going to get rid of the table definition for now. --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( id : Int, name: String, year: Int, students: List[Prof] ) ```
??? - Ok so what's wrong with this representatoin for IDs? (new objects) --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( id : Option[Int], name: String, year: Int, students: List[Prof] ) ```
??? - Ok is this any better? - ... - Maybe a little bit, but I think it's irritating because you tend to have three cases: 1. it's new, and we know it's new 2. it's from the database so we know it has an id 3. we're doing some kind of computation that's only looking at the structure and we don't care about database id And this encoding is irritating in all three cases, so I don't like it. So a way to make the id less invasive is to externalize it. --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( name: String, year: Int, students: List[Prof] ) type IdProf = (Int, Prof) ```
??? - so ... - but the problem now is that the children don't have ids, right? So we have to do this: --- # Recursive Data A recursive data type for professors and their Ph.D. students. ```scala case class Prof( name: String, year: Int, students: List[(Int, Prof)] ) type IdProf = (Int, Prof) ```
??? - ... Which defeats the purpose of externalizing the ids … the whole point was to not have to talk about them in the model. So let's try something else. Let's parameterize it on the child type. --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala type Prof = ProfF[ProfF] type IdProf = (Int, ProfF[(Int, ProfF)]) ```
??? - ok so the data type isn't recursive anymore - And I'm going to call this `ProfF` just to distinguish it from our old `Prof`, so now we can just say ... - right? no, because ProfF has a type parameter --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala type Prof = ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ProfF[ type IdProf = (Int, ProfF[(Int, ProfF[(Int, ProfF[(Int, ProfF[(Int, ProfF[(Int, ProfF[(Int, ProfF[(Int, ProfF[(Int, ```
??? - so this doesn't work because the types are infinite --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala type Prof = ProfF[Prof] type IdProf = (Int, ProfF[IdProf]) ```
??? - what if we make the type aliases self-referential? - ok? no. doesn't compile - type aliases can't be recursive. but **classes** can ... --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala case class Prof(value: ProfF[Prof]) case class IdProf(id: Int, value: ProfF[IdProf]) ``` ??? - So what if we make these case classes? Does this work? - So this is cool, we have one representation for our data type, `ProfF`, and depending on how we wrap it we can represent just the pure data *or* the data annotated with database ids. - We could claim victory here because this actually does what we want. - But this is functional programming and we like abstraction, so let's push on this a little it and see if we can generalize it a little bit. - Ok, so there's nothing here's that's specific to ProfF, so let's factor that out. --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala case class Prof[F[_]](value: F[Prof]) case class IdProf[F[_]](id: Int, value: F[IdProf]) ``` ??? - But this doesn't compile because `Prof` needs a type argument, which is ... `F` right? --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala case class Prof[F[_]](value: F[Prof[F]]) case class IdProf[F[_]](id: Int, value: F[IdProf[F]]) ``` ??? - We also note that this doesn't depend on the id being an `Int` so let's factor that out too. --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala case class Prof[F[_]](value: F[Prof[F]]) case class IdProf[F[_], A](id: A, value: F[IdProf[F, A]]) ``` ??? - and we had to add the `A` to the type argument here since `IdProf` now has two type parameters. - Ok, so what do we have now? We have two recursive types that are totally generic; the first one can make any `F` recursive, and the second can make any `F` recursive *and* annotate each value with some arbitrary label. - It turns out these are well-known types. --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala case class Fix[F[_]](unfix: F[Fix[F]]) case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]) ``` ??? - the first is ... - the second is ... - and I'll mention here that `Cofree` (sometimes called the cofree comonad) is the dual of the `Free` monad, which everyone spent the last few years talking about at Scala conferences. Cofree is an A **and** an `F[Cofree[F, A]]` and Free is an `A` **or** an `F[Free[F,A]]`. So that's how they're related and that's where the name comes from. - and i'll also say that both free and cofree are really just special cases of `Fix`, and I think Greg Pfiel will have something to say about that in the talk that's coming up next. - but this illustrates what I mean about pushing on code. if you push hard enough sometimes it disappears entirely, because: --- class: center, middle ### tpolecat's law of mistaken invention: ## _"Anything I invent that is sufficiently polymorphic and plausibly useful probably already exists in scalaz."_ ??? - But in this case both scalaz and cats provide `Cofree` and neither provides `Fix`. - Ok so now that we know about the general types we can define `Prof` and `ProfF` trivially. --- # Recursive Data A ~~recursive~~ data type for professors and their Ph.D. students. ```scala case class ProfF[A]( name: String, year: Int, students: List[A] ) ``` ```scala case class Fix[F[_]](unfix: F[Fix[F]]) case class Cofree[F[_], A](head: A, tail: F[Cofree[F, A]]) ``` Annotated and un-annotated `ProfF` trees. ```scala type Prof = Fix[ProfF] type IdProf = Cofree[ProfF, Int] ``` ??? - So by this point I fear I may have lost some people, so just to get back to reality I want to show you how you can construct these things. --- # Recursive Data ```scala case class Prof(name: String, year: Int, students: List[Prof]) val p: Prof = Prof("Hilbert", 1885, List( Prof("Ackermann", 1925, Nil), Prof("Curry", 1930, Nil), Prof("Weyl", 1908, List( Prof("Mac Lane", 1934, List( Prof("Howard", 1956, Nil), Prof("Awodey", 1997, Nil) )) )) )) ```
??? - Here is our original recursive data type and a construction. Nothing fancy here. - Ok point out how much awesomeness is in this tree. --- # Recursive Data ```scala case class ProfF[A](name: String, year: Int, students: List[A]) type Prof = Fix[ProfF] val p: Prof = Fix(ProfF("Hilbert", 1885, List( Fix(ProfF("Ackermann", 1925, Nil)), Fix(ProfF("Curry", 1930,Nil)), Fix(ProfF("Weyl", 1908, List( Fix(ProfF("Mac Lane", 1934, List( Fix(ProfF("Howard", 1956, Nil)), Fix(ProfF("Awodey", 1997, Nil)) )))) ))) )) ```
??? - And here's the version with `Fix`. It's identical in structure but there's an extra `Fix` constructor wrapped around the `ProfF` constructor. --- # Recursive Data ```scala case class ProfF[A](name: String, year: Int, students: List[A]) type IdProf = Cofree[ProfF, Int] val p: IdProf = Cofree(1, ProfF("Hilbert", 1885, List( Cofree(2, ProfF("Ackermann", 1925, Nil)), Cofree(3, ProfF("Curry", 1930,Nil)), Cofree(4, ProfF("Weyl", 1908, List( Cofree(5, ProfF("Mac Lane", 1934, List( Cofree(6, ProfF("Howard", 1956, Nil)), Cofree(7, ProfF("Awodey", 1997, Nil)) )))) ))) )) ```
??? - And here's the `Cofree` version, which also has an annotation (an `Int` in this case) associated with each node. - So even though the types here are a little challenging at first and the names are kind of intimidating, but it's just data. You can construct them, you can pattern match on them, and so on. Not scary. -
--- class: center, middle # Mezzanine ??? - Ok, so before we get back to our database problem I want to take a detour and show you an example of programming with these types in a totally pure context, without worrying about IO effects. - So we're going to write some parsers. --- # Parse Positions ```scala case class ProfF[A](name: String, year: Int, students: List[A]) val data = """|Simeon Denis Poisson, 1800 | Gustav Peter Lejeune Dirichlet, 1827 | Rudolf Otto Sigismund Lipschitz, 1853 | C. Felix (Christian) Klein, 1868 | William Edward Story, 1875 | Solomon Lefschetz, 1911 | Albert William Tucker, 1932 | Marvin Lee Minsky, 1954 | Gerald Jay Sussman, 1973 | Guy Lewis Steele, 1980 | Philip Lee Wadler, 1984 | C. L. Ferdinand (Carl Louis) Lindemann, 1873 | David Hilbert, 1885 | Wilhelm Ackermann, 1925 | Haskell Curry, 1930 | Hermann Weyl, 1908 | Saunders Mac Lane, 1934 | Steven Awodey, 1997 | William Howard, 1956 |""".stripMargin ``` ??? So, here's some sample data that we want to parse into our fixpoint types. You may recognize some of these names. --- # Parse Positions ```scala def prof(n: Int): Parser[Fix[ProfF]] = for { _ <- manyN(n, char(' ')) // skip 'n' spaces name <- stringOf(notChar(',')) // read up to a comma _ <- token(char(',')) // skip comma and following space year <- int // read an int _ <- char('\n') // skip a newline ss <- many(prof(n + 2)) // recursively read more at indent + 2 } yield Fix(ProfF(name, year, ss)) ``` ??? - And here's one way to do it. This is written with `atto` which is a parsing library I work on but it would look the same with Li Haoyi's Fastparse or pretty much any monadic parser combinator library. -
--- # Parse Positions ```scala def prof(n: Int): Parser[Fix[ProfF]] = for { _ <- manyN(n, char(' ')) // skip 'n' spaces name <- stringOf(notChar(',')) // read up to a comma _ <- token(char(',')) // skip comma and following space year <- int // read an int _ <- char('\n') // skip a newline ss <- many(prof(n + 2)) // recursively read more at indent + 2 } yield Fix(ProfF(name, year, ss)) ``` ```scala scala> prof(0).parseOnly(data).option res7: Option[Fix[ProfF]] = Some(Fix(ProfF(Simeon Denis Poisson, 1800, «1»))) ``` ??? - and it works! - but the `toString` for `Fix` isn't that great so I'll call a utility method that prints out the tree. I'm not going to show it to you but it's in the example code. --- # Parse Positions ```scala scala> prof(0).parseOnly(data).option.foreach(drawFix) ProfF(Simeon Denis Poisson, 1800, «1») ProfF(Gustav Peter Lejeune Dirichlet, 1827, «1») ProfF(Rudolf Otto Sigismund Lipschitz, 1853, «1») ProfF(C. Felix (Christian) Klein, 1868, «2») ProfF(William Edward Story, 1875, «1») ProfF(Solomon Lefschetz, 1911, «1») ProfF(Albert William Tucker, 1932, «1») ProfF(Marvin Lee Minsky, 1954, «1») ProfF(Gerald Jay Sussman, 1973, «1») ProfF(Guy Lewis Steele, 1980, «1») ProfF(Philip Lee Wadler, 1984, «0») ProfF(C. L. Ferdinand (Carl Louis) Lindemann, 1873, «1») ProfF(David Hilbert, 1885, «3») ProfF(Wilhelm Ackermann, 1925, «0») ProfF(Haskell Curry, 1930, «0») ProfF(Hermann Weyl, 1908, «1») ProfF(Saunders Mac Lane, 1934, «2») ProfF(Steven Awodey, 1997, «0») ProfF(William Howard, 1956, «0») ``` ??? - right. that looks good. - now let's see what we can do with `Cofree`. --- # Parse Positions ```scala def prof(n: Int): Parser[Fix[ProfF]] = for { _ <- manyN(n, char(' ')) // skip 'n' spaces name <- stringOf(notChar(',')) // read up to a comma _ <- token(char(',')) // skip comma and following space year <- int // read an int _ <- char('\n') // skip a newline ss <- many(prof(n + 2)) // recursively read more at indent + 2 } yield Fix(ProfF(name, year, ss)) ``` ??? - Here's our `Fix` parser ... --- # Parse Positions ```scala def posProf(n: Int): Parser[Cofree[ProfF, (Int, Int)]] = for { p0 <- pos _ <- manyN(n, char(' ')) // skip 'n' spaces name <- stringOf(notChar(',')) // read up to a comma _ <- token(char(',')) // skip comma and following space year <- int // read an int _ <- char('\n') // skip a newline ss <- many(posProf(n + 2)) // recursively read more at indent + 2 p1 <- pos } yield Cofree((p0, p1), ProfF(name, year, ss)) ``` ??? - And here's one with `Cofree`, and what we're doing here is annotating each `ProfF` with the starting and ending parse positions. --- # Parse Positions ```scala def posProf(n: Int): Parser[Cofree[ProfF, (Int, Int)]] = for { p0 <- pos _ <- manyN(n, char(' ')) // skip 'n' spaces name <- stringOf(notChar(',')) // read up to a comma _ <- token(char(',')) // skip comma and following space year <- int // read an int _ <- char('\n') // skip a newline ss <- many(posProf(n + 2)) // recursively read more at indent + 2 p1 <- pos } yield Cofree((p0, p1), ProfF(name, year, ss)) ``` ```scala scala> posProf(0).parseOnly(data).option res9: Option[Cofree[ProfF,(Int, Int)]] = Some(Cofree((0,713),ProfF(Simeon Denis Poisson, 1800, «1»))) ``` ???  - So our original idea for `Cofree` was for database IDs but we can use that slot for anything. Without any changes to our API we now have a representation with source positions. - And you can see how this can be really useful for something like a computer language, because your recursive data type is an AST that you might want to annotate with source positions, types, strictness analysis, any number of things, and by encoding your data types this way you get that ability for free, which is really nice. - Ok, so back to our database problem. --- class: center, middle # Ok, not quite yet. Almost. ??? - Ok so before we do that I need to explain something that you may have been wondering about. --- # So Why the F? ```scala case class ProfF[A](name: String, year: Int, students: List[A]) ``` `ProfF` is a functor. This means we can map over it. ```scala implicit val PersonFunctor: Functor[ProfF] = new Functor[ProfF] { def map[A, B](fa: ProfF[A])(f: A => B): ProfF[B] = fa.copy(students = fa.students.map(f)) } ``` Thus. ```scala scala> val ps = ProfF("Bob", 1976, List("foo", "bar")) ps: ProfF[String] = ProfF(Bob,1976,List(foo, bar)) scala> ps.map(s => s.length) res11: ProfF[Int] = ProfF(Bob,1976,List(3, 3)) ``` ??? - ProfF is a functor. This means we can map over it. - And if you follow this design pattern your data type will *always* be a functor, in fact it's called a pattern functor, so that's the thing to google if you want to learn more about this kind of thing. - In any case the functor here is straightforward because we can just delegate to `.map` on `List` and we're done. --- # But wait, there's more! ```scala case class ProfF[A](name: String, year: Int, students: List[A]) ``` `ProfF` is a *traversable* functor. This means we can sequence it. ```scala implicit val PersonTraverse: Traverse[ProfF] = new Traverse[ProfF] { def traverseImpl[G[_]: Applicative, A, B](fa: ProfF[A])(f: A => G[B]): G[ProfF[B]] = fa.students.traverse(f).map(ss => fa.copy(students = ss)) } ``` Thus. ```scala scala> val p = ProfF("Bob", 1975, List(Option(1), Option(2))) p: ProfF[Option[Int]] = ProfF(Bob,1975,List(Some(1), Some(2))) scala> p.sequence res12: Option[ProfF[Int]] = Some(ProfF(Bob,1975,List(1, 2))) ``` ??? - It turns out that `ProfF` is also a **traversable** functor. This means we can turn a `ProfF[F[A]]` into a `F[ProfF[A]]` if `F` is an applicative functor. We can flip the type constructors, which is what the example illustrates. Look at the types. - The implementation is a little more involved but again we just delegate to `traverse` on `List` for most of the work because `List` is also a traversable functor. --- # (small digression) Because "map and then sequence" is so common, we also have `traverse` which does them in one step. You can define one in terms of the other but they have this relationship: ```scala fa.map(f).sequence <~> fa.traverse(f) // (1) definition of traverse ``` And we can find another identity by equational reasoning. ```scala fa <~> fa.map(identity) // (2) the functor law fa.sequence <~> fa.map(identity).sequence // by (2) above fa.sequence <~> fa.traverse(identity) // by (1) above ``` So when you're working with traversable functors it's nice to know both of those substitutions. ??? - and by `<~>` we mean "the same thing" ... you can freely substitute one for the other. - and given that we can find another identity - this is kind of a trivial example but again it's just that's not in your toolchest when you're first learning about functional programming and I always like to give examples when I can. - Ok. --- class: center, middle # Can we do some SQL now? --- # Get your doobie on Doobie is a **pure functional** (i.e., side-effect free) JDBC library for Scala. See `tpolecat/doobie` for doc, presentations, etc. ```scala // a transactor abstracts over connection pools and io-effect types val xa = DriverManagerTransactor[IO]("org.h2.Driver", "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", "") // a program to create the schema val create: ConnectionIO[Int] = sql""" CREATE TABLE prof ( id INTEGER IDENTITY, parent INTEGER NULL, name VARCHAR NOT NULL, year INTEGER NOT NULL, FOREIGN KEY(parent) REFERENCES prof(id) ); """.update.run ``` Let's init the database. ```scala scala> create.transact(xa).unsafePerformIO res16: Int = 0 scala> sql"select id from prof".query[Int].list.transact(xa).unsafePerformIO res17: List[Int] = List() ``` ??? - Ok so I don't have time to explain doobie in detail, but the big idea is that Doobie programs are values. They're data. They don't "do" anything until you translate them to some target type like `IO` or `Task` and run it ("at the end of the world" as we say). - So here ... - And that's about all we need to know right now. --- # Insert a Tree ```scala def insertNode(op: Option[Int], p: ProfF[_]): ConnectionIO[Int] = sql""" INSERT INTO prof (parent, name, year) VALUES ($op, ${p.name}, ${p.year}) """.update.withUniqueGeneratedKeys("id") ``` ??? - Ok so here's a method that constructs a program that inserts a row into the `prof` table and yields the generated id. - (explain) - It disregards the childern entirely, which you know because of the exstential placeholder; the implementation can't do anything with the children because it doesn't even know what type they are. - --- # Insert a Tree ```scala def insertNode(op: Option[Int], p: ProfF[_]): ConnectionIO[Int] = sql""" INSERT INTO prof (parent, name, year) VALUES ($op, ${p.name}, ${p.year}) """.update.withUniqueGeneratedKeys("id") def insertTree(fp: Fix[ProfF], op: Option[Int]): ConnectionIO[Cofree[ProfF, Int]] = for { h <- insertNode(op, fp.unfix) // ConnectionIO[Int] t <- fp.unfix // ProfF[Fix[ProfF]] .map(insertTree(_, Some(h))) // ProfF[ConnectionIO[Cofree[ProfF, Int]]] .sequence // ConnectionIO[ProfF[Cofree[ProfF, Int]]] } yield Cofree(h, t) ``` ??? - And here's a metohod that constructs a program to insert a `Fix[ProfF]` into the database, and yield another tree with the same structure but annotated with database ids. Which is what we wanted to do. - So how does this work? - (explain) - ok so we know that `.map` and then `.sequence` is `.traverse` so let's simplify that --- # Insert a Tree ```scala def insertNode(op: Option[Int], p: ProfF[_]): ConnectionIO[Int] = sql""" INSERT INTO prof (parent, name, year) VALUES ($op, ${p.name}, ${p.year}) """.update.withUniqueGeneratedKeys("id") def insertTree(fp: Fix[ProfF], op: Option[Int]): ConnectionIO[Cofree[ProfF, Int]] = for { h <- insertNode(op, fp.unfix) t <- fp.unfix .traverse(insertTree(_, Some(h))) // same as map + sequence } yield Cofree(h, t) ``` ??? - (next slide) --- # Insert a Tree ```scala def insertNode(op: Option[Int], p: ProfF[_]): ConnectionIO[Int] = sql""" INSERT INTO prof (parent, name, year) VALUES ($op, ${p.name}, ${p.year}) """.update.withUniqueGeneratedKeys("id") def insertTree(fp: Fix[ProfF], op: Option[Int]): ConnectionIO[Cofree[ProfF, Int]] = for { h <- insertNode(op, fp.unfix) t <- fp.unfix.traverse(insertTree(_, Some(h))) } yield Cofree(h, t) ``` ??? - So, this `insertTree` operation can be generalized but the `Option` type makes it a little messy so we're just going to leave it as-is. --- # Insert a Tree ```scala scala> val p = prof(0).parseOnly(data).option.get // yolo p: Fix[ProfF] = Fix(ProfF(Simeon Denis Poisson, 1800, «1»)) scala> val io = insertTree(p, None).transact(xa).flatMap(c => ioDrawCofree(c)) io: scalaz.effect.IO[Unit] = scalaz.effect.IOFunctions$$anon$6@57653a55 scala> io.unsafePerformIO 1 :< ProfF(Simeon Denis Poisson, 1800, «1») 2 :< ProfF(Gustav Peter Lejeune Dirichlet, 1827, «1») 3 :< ProfF(Rudolf Otto Sigismund Lipschitz, 1853, «1») 4 :< ProfF(C. Felix (Christian) Klein, 1868, «2») 5 :< ProfF(William Edward Story, 1875, «1») 6 :< ProfF(Solomon Lefschetz, 1911, «1») 7 :< ProfF(Albert William Tucker, 1932, «1») 8 :< ProfF(Marvin Lee Minsky, 1954, «1») 9 :< ProfF(Gerald Jay Sussman, 1973, «1») 10 :< ProfF(Guy Lewis Steele, 1980, «1») 11 :< ProfF(Philip Lee Wadler, 1984, «0») 12 :< ProfF(C. L. Ferdinand (Carl Louis) Lindemann, 1873, «1») 13 :< ProfF(David Hilbert, 1885, «3») 14 :< ProfF(Wilhelm Ackermann, 1925, «0») 15 :< ProfF(Haskell Curry, 1930, «0») 16 :< ProfF(Hermann Weyl, 1908, «1») 17 :< ProfF(Saunders Mac Lane, 1934, «2») 18 :< ProfF(Steven Awodey, 1997, «0») 19 :< ProfF(William Howard, 1956, «0») ``` ??? - so first we parse the value like we did before - then we construct a program to insert it, passing the result to `ioDrawCofree` which is the same printing code, just in `IO` so it doesn't side-effect. - Then we run the program and see that we get back an annotated tree. - It starts with 1 which is a little suspicious, so let's do it again ... --- # Insert a Tree ```scala scala> io.unsafePerformIO 20 :< ProfF(Simeon Denis Poisson, 1800, «1») 21 :< ProfF(Gustav Peter Lejeune Dirichlet, 1827, «1») 22 :< ProfF(Rudolf Otto Sigismund Lipschitz, 1853, «1») 23 :< ProfF(C. Felix (Christian) Klein, 1868, «2») 24 :< ProfF(William Edward Story, 1875, «1») 25 :< ProfF(Solomon Lefschetz, 1911, «1») 26 :< ProfF(Albert William Tucker, 1932, «1») 27 :< ProfF(Marvin Lee Minsky, 1954, «1») 28 :< ProfF(Gerald Jay Sussman, 1973, «1») 29 :< ProfF(Guy Lewis Steele, 1980, «1») 30 :< ProfF(Philip Lee Wadler, 1984, «0») 31 :< ProfF(C. L. Ferdinand (Carl Louis) Lindemann, 1873, «1») 32 :< ProfF(David Hilbert, 1885, «3») 33 :< ProfF(Wilhelm Ackermann, 1925, «0») 34 :< ProfF(Haskell Curry, 1930, «0») 35 :< ProfF(Hermann Weyl, 1908, «1») 36 :< ProfF(Saunders Mac Lane, 1934, «2») 37 :< ProfF(Steven Awodey, 1997, «0») 38 :< ProfF(William Howard, 1956, «0») ``` ??? - and yeah, it really is using database sequence to get the ids. - I should mention that this whole talk is one long REPL session that has been typechecked and executed, I just haven't been showing output. I use a tool called **tut** to do this. - Ok, so now how do we read trees back? --- # And now read it back. ```scala def readNode(id: Int): ConnectionIO[ProfF[Int]] = for { d <- sql"SELECT name, year FROM prof WHERE id = $id".query[(String, Int)].unique ss <- sql"SELECT id FROM prof WHERE parent = $id".query[Int].list } yield ProfF(d._1, d._2, ss) ``` ??? - Here's a method that constructs a program to compute a `ProfF[Inf]` ... no what does that mean? It's a `ProfF` whose children are database ids. So instead of object references we have database references. - I think this is a really nice consequence of this encoding; sometimes you want the whole structure and sometimes you just want a "local" hunk, and we get both with the same data type. - I should acknowledge that this is a very inefficient way to do this; it would be much faster to read the whole thing into memory and assemble the tree locally, but this is easier to follow and ends up being a better example. - So now that we have a way to read a slice with database references, how do we assemble this into a tree? --- # And now read it back. ```scala def readNode(id: Int): ConnectionIO[ProfF[Int]] = for { d <- sql"SELECT name, year FROM prof WHERE id = $id".query[(String, Int)].unique ss <- sql"SELECT id FROM prof WHERE parent = $id".query[Int].list } yield ProfF(d._1, d._2, ss) def readTree(id: Int): ConnectionIO[Cofree[ProfF, Int]] = readNode(id).flatMap { pi => pi.map(readTree) // ProfF[ConnectionIO[Cofree[ProfF, Int]]] .sequence // ConnectionIO[ProfF[Cofree[ProfF, Int]]] .map(Cofree(id, _)) // ConnectionIO[Cofree[ProfF, Int]] } ``` ??? - here we go. (explain) - as before we know that `.map` and then `.sequence` is ... --- # And now read it back. ```scala def readNode(id: Int): ConnectionIO[ProfF[Int]] = for { d <- sql"SELECT name, year FROM prof WHERE id = $id".query[(String, Int)].unique ss <- sql"SELECT id FROM prof WHERE parent = $id".query[Int].list } yield ProfF(d._1, d._2, ss) def readTree(id: Int): ConnectionIO[Cofree[ProfF, Int]] = readNode(id).flatMap { pi => pi.traverse(readTree) .map(Cofree(id, _)) } ``` ??? - (next) --- # And now read it back. ```scala def readNode(id: Int): ConnectionIO[ProfF[Int]] = for { d <- sql"SELECT name, year FROM prof WHERE id = $id".query[(String, Int)].unique ss <- sql"SELECT id FROM prof WHERE parent = $id".query[Int].list } yield ProfF(d._1, d._2, ss) def readTree(id: Int): ConnectionIO[Cofree[ProfF, Int]] = readNode(id).flatMap(_.traverse(readTree).map(Cofree(id, _))) ``` ??? - Ok so I'd like to take a minute to look at the `readTree` method more closely and see if we can generalize it. --- # (another digression) ```scala // our original method for reading a tree def readTree(id: Int): ConnectionIO[Cofree[ProfF, Int]] = readNode(id).flatMap(_.traverse(readTree).map(Cofree(id, _))) ``` ??? - Let's factor out the call to `readNode`. --- # (another digression) ```scala // factor out the function we're calling def readTree(id: Int)(f: Int => ConnectionIO[ProfF[Int]]): ConnectionIO[Cofree[ProfF, Int]] = f(id).flatMap(_.traverse(readTree(_)(f)).map(Cofree(id, _))) ``` ??? - Ok, so `f` gives us a `ConnectionIO` but all we're doing with it is calling `.flatMap` and then `.map`, so it should work with any monad. Let's factor that out. --- # (another digression) ```scala // factor out the monad def readTree[M[_]: Monad](id: Int)(f: Int => M[ProfF[Int]]): M[Cofree[ProfF, Int]] = f(id).flatMap(_.traverse(readTree(_)(f)).map(Cofree(id, _))) ``` ??? - So now we get an that `M` of `ProfF[Int]` but the only thing we're doing with the `ProfF` it is calling `.traverse`, so it should work with any traversable functor. Let's factor that out. --- # (another digression) ```scala // factor out the traversable functor def readTree[M[_]: Monad, F[_]: Traverse](id: Int)(f: Int => M[F[Int]]): M[Cofree[F, Int]] = f(id).flatMap(_.traverse(readTree(_)(f)).map(Cofree(id, _))) ``` ??? - And we're not doing anything with the `Int` but passing it as an argument so let's factor that out too. --- # (another digression) ```scala // factor out the Int def readTree[M[_]: Monad, F[_]: Traverse, A](a: A)(f: A => M[F[A]]): M[Cofree[F, A]] = f(a).flatMap(_.traverse(readTree(_)(f)).map(Cofree(a, _))) ``` ??? - ok, so now we have something definitely useful and totally generic. --- # (another digression) ```scala // we now have a generic monadic unfold into cofree def unfoldCM[M[_]: Monad, F[_]: Traverse, A](a: A)(f: A => M[F[A]]): M[Cofree[F, A]] = f(a).flatMap(_.traverse(unfoldCM(_)(f)).map(Cofree(a, _))) ``` ??? - This is monadic cofree corecursion; it takes a seed value and feeds it into a function that generates an F in some context, the traverses it to expand the `A`'s in the `F`, forever, or until there are no more `A`s; in this case it means we're at the leaves of the tree. - And what it gives back is a Cofree annotated with the key values. - And does this method exist in scalaz already? NO! The non-monadic version does but not this one. It's an oversight. --- # (another digression) ```scala // we now have a generic monadic unfold into cofree def unfoldCM[M[_]: Monad, F[_]: Traverse, A](a: A)(f: A => M[F[A]]): M[Cofree[F, A]] = f(a).flatMap(_.traverse(unfoldCM(_)(f)).map(Cofree(a, _))) // and we can define readTree in terms of it def readTree(id: Int): ConnectionIO[Cofree[ProfF, Int]] = unfoldCM(id)(readNode) ``` ??? - so in any case, with this method our `readTree` method is trivial. - and I want to point out it's worth doing this **even if you're only calling it once** because the more polymorphic your code is, the fewer ways there are to write it because you have fewer operations available. So that means there are fewer ways to write it wrong. And in fact sometimes if it typechecks it has to be correct because there's only one way to do it. - But does it work? --- # Do it work? Let's read Hilbert's sub-tree (id = 32). ```scala scala> val io = readTree(32).transact(xa).flatMap(c => ioDrawCofree(c)) io: scalaz.effect.IO[Unit] = scalaz.effect.IOFunctions$$anon$6@5ff635a8 scala> io.unsafePerformIO 32 :< ProfF(David Hilbert, 1885, «3») 33 :< ProfF(Wilhelm Ackermann, 1925, «0») 34 :< ProfF(Haskell Curry, 1930, «0») 35 :< ProfF(Hermann Weyl, 1908, «1») 36 :< ProfF(Saunders Mac Lane, 1934, «2») 37 :< ProfF(Steven Awodey, 1997, «0») 38 :< ProfF(William Howard, 1956, «0») ``` ??? - yes! - and I think it's really cool that we're using a totally generic monadic unfold to do database programming. We never once thought "hey we're talking to a database here so we need to be careful, we have a connection and a resultset and iteration" and all that ... we just went where the types took us. - Ok, so what have we seen? --- # Review - We learned about some recursive types. - We used them to do something useful (or at least interesting). - We pushed on our code and did some equational reasoning. - We were not frightened. ??? - `Fix` and `Cofree` popped out of our model naturally just by pushing a little bit; it's not a contrived example, the question of what to do with database IDs is a real thing we think about. - And we used them to represent the same data type in a bunch of different ways: as a simple recursive data type, as an isolated node with unknown child types, as as tree annotated with parse positions, as a node with database references rather than object references, and of course as a tree annotated with database ids. We did all of this with the same definition of `ProfF`. - We did some code pushing. Not much more to say about that, I just wanted to demonstrate the way we think about things when we do FP with expressive types, so hopefully even if you didn't follow all of it you get a sense for how powerful it is. - And hopefully you all survived. And if not I have bad news for you because Greg Pfiel is up next and he's going to be talking about using recursion schemes in a much more general and more powerful way. - sooooo, that's it. --- class: center, middle # Thanks! Code and slides at `tpolecat/cofree` on GitHub ## Questions?


API description
The following table displays and briefly explains the methods exposed by the Socios SOAP API.
The functionality described below is implemented only for the social networks that support it and the implementation is subject to the
limitations imposed by each social network. Only information marked as "public" can be retrieved.
If some information in a social network is marked as "private" by its owner, it cannot be retrieved by the following methods.
In searches accepting a list of social networks as an input parameter, if the field is empty, all social networks are included in the
search.
- GetPersons
- ConnectedPersons
- MyConnectedPersons
- FindPersons
- GetMediaItems
- GetMediaItemsForUser
- GetMediaItemsForPage
- FindMediaItems
- FindRelevantMediaItems
- GetActivities
- GetActivitiesForUser
- FindActivities
- GetComments
- GetCommentsForMediaItem
- GetCommentsForActivity
- PostMessage
WSDL
GetPersons
Input :
- personIds : List of ObjectId objects, each one defining a user in a social network.
Description :
Returns the respective users.
ConnectedPersons
Input :
- personId : an ObjectId that defines a user in a social network.
Description :
Returns the contacts of the user. Depending on the social network, the result can include friends, followers, followees etc.
MyConnectedPersons*
Input :
- personId : an ObjectId that defines a user in a social network.
Description :
Returns the contacts of the user. Depending on the social network, the result can include friends, followers, followees etc.
* This method requires an authentication token.
FindPersons
Input :
- personFilter : a PersonFilter object.
- mediaItemId : an ObjectId that defines a media item in a social network.
- activityId : an ObjectId that defines an activity in a social network.
- username : an ObjectId that defines a user in a social network.
Description :
This method searches for users based on which input is provided (all other inputs have to be null).
When the personFilter is passed as input, the method searches for users whose profile information contains all of the filter's keywords.
If the mediaItemId is provided, the method returns users associated with the media item. The results can contain the owner of the media
item, users that have liked the media item, commented on it or users that were tagged in it.
When the activityId is given, the method retrieves users associated with the corresponding activity, similarly to the previous case.
Finally, when the username is provided, the method gets the user that has the exact username in the specified social network.
GetMediaItemsForPage
Input :
- pageId : an ObjectId that defines a social network's Page.
Description :
This method returns the posts published on the page.
GetActivities
Input :
- activityIds : List of ObjectId objects, each one defining an activity in a social network.
Description :
Returns the respective activities.
GetActivitiesForUser
Input :
- personId : an ObjectId that defines a user in a social network.
Description :
Returns the activities performed by the user.
FindActivities
Input :
- activityFilter : an ActivityFilter object.
Description :
This method returns activities based on the keywords and language specified in the filter.
PostMessage*
Input :
- personId : an ObjectId that defines a user in a social network.
- postText : the message the user wants to post.
Posts a message on behalf of the user and returns the id of the new post.
* This method requires an authentication token